这是一个简单的monad例子吗?

时间:2012-09-08 09:36:50

标签: clojure monads

这是我在观看this后尝试修改monadic功能。

h使用bind将两个任意函数fg组合在一起。在这种情况下,unit运算符是什么?

;; f :: int -> [str]
;; g :: str -> [keyword]
;; bind :: [str] -> (str -> [keyword]) -> [keyword]
;; h :: int -> [keyword]

(defn f [v]
  (map str (range v)))

(defn g [s]
  (map keyword (repeat 4 s)))

(defn bind [l f]
  (flatten
   (map f l)))

(f 8)   ;; :: (0 1 2 3 4 5 6 7)
(g "s") ;; :: (:s :s :s :s)

(defn h [v]
  (bind (f v) g))

(h 9) 
;; :: (:0 :0 :0 :0 :1 :1 :1 :1 :2 :2 :2 :2 :3 :3 :3 :3 :4 :4 :4 :4 :5 :5 :5 :5)

啊,谢谢你的评论;我看到我感到困惑的地方。

我熟悉这些函数以及如何使用bind组合它们:

f0 :: a -> M a
g0 :: a -> M a

但没有这些功能:

f1 :: a -> M b
g1 :: b -> M c

但实际上,如果bind相同,M运算符对于这两种情况都是相同的。就我而言,M是列表monad,因此f1g1可以与f0g0相同的方式进行组合。

2 个答案:

答案 0 :(得分:1)

这是一个列表monad,因此unit运算符是 x ↦[ x ],即

(defn return [x] [x])

(在具有相同名称和目的的Haskell函数之后调用return。)

通过检查它是否满足the monad laws

,可以看出这是单位运算符
(bind (return a) f) => (bind [a] f) 
      => (flatten (map f [a])) => (flatten [f a]) => f a  ;; f returns a vector

同样适用于(bind x return)

答案 1 :(得分:1)

您是否尝试实施列表monad?如果是这样,那么它将是:

(defn unit [x]
  [x])

这基于Haskell implementation

instance  Monad []  where
    m >>= k             = foldr ((++) . k) [] m
    return x            = [x]