表达式的类型和值是什么:
do [1,2,3]; "lambda"
我测试了它,发现它只打印lambda 3次。 但我不明白为什么会那样做。 我怎么能用bind重写它。感觉有必要重写它。
答案 0 :(得分:6)
您的代码与
相同[1, 2, 3] >> "lambda"
>>
定义为
m >> n = m >>= \_ -> n
>>=
运算符的列表定义为:
xs >>= f = concat (map f xs)
因此,您的代码可能会被翻译成:
concat $ map (const "lambda") [1, 2, 3]
产生结果
"lambdalambdalambda"
答案 1 :(得分:0)
这是与bind相同的输出:
λ> [1,2,3] >>= \x -> "lambda"
"lambdalambdalambda"
你期望得到什么?
答案 2 :(得分:0)
按照列表monad的定义,
do [1,2,3]; "lambda" -- "lambda" = ['l','a','m','b','d','a']
= [1,2,3] >>= (\x -> "lambda")
= [r | x <- [1,2,3], r <- "lambda"]
列表monad return x = [x]
,以及
do x <- [1,2,3]; return x
= [r | x <- [1,2,3], r <- [x]]
获得[x | x <- [1,2,3]]
的快捷方式。这使用monad法 m >>= return = m
。
但是do
序列中类型m a
(此处为[a]
)的最后一个monadic值不必是单例列表。它可以是空的,也可以包含多个元素。
至于结果的类型,它是[Char]
。首先,do
代表 bind 链, bind 的类型是
(>>=) :: m a -> ( a -> m b) -> m b
由于在您的示例中,monadic值是列表,因此我们得出结论m = []
。最后一个值是String
类型[Char]
,因此根据上面的签名,这是结果的类型。