这个奇怪的monad如何绑定工作?

时间:2017-06-23 23:56:56

标签: list haskell return bind monads

这可能是一个非常的菜鸟问题,但我正在玩Haskell中的绑定运算符,我遇到了一种使用它重复字符串的方法。

[1..3] >>= const "Hey"
-- Yields "HeyHeyHey"
[1..3] >>= return "Hey"
-- Also yields the same result

我理解>>= (\_ -> return "Hey")如何产生["Hey", "Hey", "Hey"],但我不明白为什么(\_ -> "Hey")重复字符串或为什么>>= return "Hey"做同样的事情。

2 个答案:

答案 0 :(得分:8)

  

我了解>>= (\_ -> return "Hey")如何产生["Hey", "Hey", "Hey"]

右。在这种情况下,return "Hey"["Hey"]相同,因为

instance Monad [] where
  return x = [x]

所以

([1..3] >>= \_ -> return "Hey")
  ≡  ([1..3] >>= \_ -> ["Hey"])
  ≡  ["Hey"] ++ ["Hey"] ++ ["Hey"]
  ≡  ["Hey", "Hey", "Hey"]

现在,>>= (\_ -> "Hey")也可以用lambda中的list-result编写,因为字符串只是字符列表。

([1..3] >>= \_ -> "Hey")
  ≡  ([1..3] >>= \_ -> ['H','e','y'])
  ≡  ['H','e','y'] ++ ['H','e','y'] ++ ['H','e','y']
  ≡  ['H','e','y','H','e','y','H','e','y']
  ≡  "HeyHeyHey"

至于>>= return "Hey",这是一个不同的野兽。 return属于一个完全不同的monad,即 function functor

instance Monad (x->) where
  return y = const y

因此,明确([1..3] >>= const "Hey")([1..3] >>= return "Hey")给出了相同的结果:在该示例中,return只是const的另一个名称!< / p>

答案 1 :(得分:6)

此处使用的return不适用于列表monad,而是适用于此定义所包含的函数monad:

return x = \_ -> x

所以这与:

相同
[1,2,3] >>= (\_ -> "Hey")

由于(>>=)与列表的concatMap相同,我们有:

concatMap (\_ -> "Hey") [1,2,3]

你能看出为什么会产生"HeyHeyHey"吗?