【问题标题】:This is not a monad, right?这不是单子,对吧?
【发布时间】:2013-12-05 00:35:57
【问题描述】:

我看到两个消息来源说以下是一个身份单子。但我不认为这是真的,因为它不符合第三单子定律。

(defn result [v] (fn [] v))
(defn bind [mv f] (f (mv))

第三单子定律失败

(bind (bind (result 3) identity) identity)

内部bind调用返回3,不是monadic值,所以Java返回尝试调用函数的错误(3)。

我错过了什么吗?

【问题讨论】:

    标签: clojure monads identity


    【解决方案1】:

    bindresult 的定义很好,确实构成了一个 monad。但是,identity 不是为您的 monad 传递给 bind 的合法函数。在 Haskell 中,这不会通过类型检查器,因为

    bind :: (Monad m) => m a -> (a -> m b) -> m b
    

    这里的第二个参数是你的f,在本例中是identity。但是identity :: a -> a 不适合bindf 所需的类型。

    为了在你的 monad 中使用“类似身份”的东西,你需要将 identityresult 组合到 monad 中。例如,

    (let [id (comp result identity)] ;; or (liftm identity), if you have liftm
      (bind (bind (result 3) id) id))
    

    返回(result 3),即(fn [] 3)

    编辑

    我对此进行了更多思考,因为我断言 a -> a 是与 a -> m b 不兼容的类型显然不太正确:如果您让 a 成为 m b,则类型确实匹配。所以在某些情况下可以使用identity 作为bind 函数。具体来说,如果您的原始输入是(result (result 3)),您可以bind identity 并直接退出(result 3)。其实(bind identity x)基本上就是(join x)!这并不完全是新闻——我已经读过很多遍了——但我想它还没有深入人心,或者我一开始就更正确地回答了这个问题。

    无论如何,我只是想分享一下,因为它有点话题,应该充实我的答案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-04
      • 2016-12-30
      • 1970-01-01
      • 2014-09-17
      • 2020-12-22
      • 2011-06-30
      • 2015-08-10
      相关资源
      最近更新 更多