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

Luí*_*rix 1 monads haskell bind return list

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

[1..3] >>= const "Hey"
-- Yields "HeyHeyHey"
[1..3] >>= return "Hey"
-- Also yields the same result
Run Code Online (Sandbox Code Playgroud)

我明白如何>>= (\_ -> return "Hey")屈服["Hey", "Hey", "Hey"]但我不明白为什么(\_ -> "Hey")重复字符串或为什么>>= return "Hey"同样的事情.

lef*_*out 8

我明白如何>>= (\_ -> return "Hey")屈服["Hey", "Hey", "Hey"]

对.return "Hey"在这种情况下是相同的["Hey"],因为

instance Monad [] where
  return x = [x]
Run Code Online (Sandbox Code Playgroud)

所以

([1..3] >>= \_ -> return "Hey")
  ?  ([1..3] >>= \_ -> ["Hey"])
  ?  ["Hey"] ++ ["Hey"] ++ ["Hey"]
  ?  ["Hey", "Hey", "Hey"]
Run Code Online (Sandbox Code Playgroud)

现在,>>= (\_ -> "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"
Run Code Online (Sandbox Code Playgroud)

至于>>= return "Hey"那是一个不同的野兽.这里return属于一个完全不同的monad,即函数functor.

instance Monad (x->) where
  return y = const y
Run Code Online (Sandbox Code Playgroud)

因此,它有点明确([1..3] >>= const "Hey")([1..3] >>= return "Hey")给出相同的结果:在那个例子中,return只是另一个名字const!

  • @naomik - 看着类型.从`[1..3]`我们知道`>> =`的左边是`Num a => [a]`,这意味着`>> =`在`实例中定义Monad []`及其右侧必须是'Num a => a - > [b]`类型.我们已经知道`return"Hey":: Monad m => m String`,所以现在我们可以声明`m String~a - > [b]`,如果我们采用`b~Char`我们可以匹配`m~( - >)a`,所以`return`必须由`实例Monad(( - >)a)`定义. (2认同)

ama*_*loy 6

return这里使用的存在是不是名单单子,但对于功能单子,在这个定义成立:

return x = \_ -> x
Run Code Online (Sandbox Code Playgroud)

所以这和:

[1,2,3] >>= (\_ -> "Hey")
Run Code Online (Sandbox Code Playgroud)

因为(>>=)concatMap列表相同,我们有:

concatMap (\_ -> "Hey") [1,2,3]
Run Code Online (Sandbox Code Playgroud)

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