【发布时间】:2020-06-18 18:37:09
【问题描述】:
所以我有这两个功能:
filterM _ [] = []
filterM p (x:xs) = do
n <- p x
ys <- filterM p xs
return (if n then x:ys else x:xs)
和
filterM _ [] = return []
filterM p (x:xs) = do
n <- p x
ys <- filterM p xs
return (if n then x:ys else x:xs)
导致以下输入的这些结果:filterM (\x -> [True,False]) [0..3]
[]
或
[[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,2,3]]
为什么return 会对执行产生如此大的影响?
【问题讨论】:
-
return []表示在列表[[]]的上下文中,这对于ys是必需的,因为如果我们返回[],那么ys“不带值”,因此结果也将是一个空列表。 -
@WillemVanOnsem 哦,当然。
return将值包装到 monad 中。这个是从[]monad 派生的,因此导致[]被包裹在[] -
强烈建议编写类型签名以避免这些问题。