这不是monad,对吗?

时间:2013-12-05 00:35:57

标签: clojure monads identity

我见过两个消息来源说以下是身份单身。但我不认为这是真的,因为它违反了第三方法。

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

失败第三个Monad法

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

内部绑定调用返回3,这不是monadic值,因此Java返回尝试调用函数(3)的错误。

我错过了什么吗?

1 个答案:

答案 0 :(得分:6)

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

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

此处的第二个参数是您的f,在本例中为identity。但identity :: a -> a不符合bind f所需的类型。

为了在你的monad中使用“类似身份”的东西,你需要通过将identityresult组合来将(let [id (comp result identity)] ;; or (liftm identity), if you have liftm (bind (bind (result 3) id) id)) 提升到monad中。例如,

(result 3)

返回(fn [] 3),即a -> a

修改

我更多地考虑了这一点,因为我断言a -> m ba是不兼容的类型显然不太正确:如果你让m b成为identity ,类型确实匹配。因此,在某些情况下,可以使用bind作为(result (result 3))函数。具体来说,如果您的原始输入为bind,则可identity (result 3)并仅(bind identity x)退出。事实上,(join x)基本上是{{1}}!这不完全是新闻 - 我已多次阅读 - 但我想它没有沉入,或者我已经开始时更正确地回答了这个问题。

无论如何,只是想我会分享这个,因为它有点局部,应该充实我的答案。