Clojure 这不是单子,对吗?
我看到两个来源说下面是一个身份单子。但我不认为这是真的,因为它不符合第三单子定律Clojure 这不是单子,对吗?,clojure,monads,identity,Clojure,Monads,Identity,我看到两个来源说下面是一个身份单子。但我不认为这是真的,因为它不符合第三单子定律 (defn result [v] (fn [] v)) (defn bind [mv f] (f (mv)) 不符合第三单子定律 (bind (bind (result 3) identity) identity) 内部绑定调用返回3,它不是一元值,因此Java返回尝试调用函数的错误(3) 我遗漏了什么吗?绑定和结果的定义很好,确实构成了单子。但是,identity不是传递给monad的bind的合法功能。在H
(defn result [v] (fn [] v))
(defn bind [mv f] (f (mv))
不符合第三单子定律
(bind (bind (result 3) identity) identity)
内部绑定调用返回3,它不是一元值,因此Java返回尝试调用函数的错误(3)
我遗漏了什么吗?绑定和结果的定义很好,确实构成了单子。但是,
identity
不是传递给monad的bind
的合法功能。在Haskell中,这不会通过typechecker,因为
bind :: (Monad m) => m a -> (a -> m b) -> m b
这里的第二个参数是您的f
,在本例中是identity
。但是identity::a->a
与bind
的f
所需的类型不匹配
为了在monad中使用“identity-like”,您需要将identity
与result
组合到monad中。比如说,
(let [id (comp result identity)] ;; or (liftm identity), if you have liftm
(bind (bind (result 3) id) id))
返回(结果3)
,即(fn[]3)
编辑
我对此做了更多的思考,因为我断言a->a
是与a->mb
不兼容的类型,这显然是不完全正确的:如果你让a
成为mb
,类型确实匹配。因此,在某些情况下,可以使用identity
作为bind
函数。具体地说,如果您的原始输入是(结果(结果3))
,您可以绑定标识,然后只退出(结果3)
。事实上,(绑定标识x)
基本上就是(加入x)
!这并不完全是新闻——我已经读了很多遍了——但我想它并没有被理解,或者我应该从一开始就更正确地回答这个问题
不管怎么说,我只是想和大家分享一下,因为这是一个话题,应该会充实我的答案