[英]Haskell: Monad return list
我正在尝试在Haskell中编写一些代码,但是我无法解决问题
f 0 = []
f n = do
x <- [0..4]
y <- x:(f (n-1))
return y
输出为:
[0,0,0,1,2,3,4,1,0,1,2,3,4,2,0,1,2,3,4,3,0,1,2,3,4,4,0,1,2,3,4,1,0,0,1,2,3,4,1,0,1,2,3,4,2,0,1,2,3,4,3,0,1,2,3,4,4,0,1,2,3,4,2,0,0,1,2,3,4,1,0,1,2,3,4,2,0,1,2,3,4,3,0,1,2,3,4,4,0,1,2,3,4,3,0,0,1,2,3,4,1,0,1,2,3,4,2,0,1,2,3,4,3,0,1,2,3,4,4,0,1,2,3,4,4,0,0,1,2,3,4,1,0,1,2,3,4,2,0,1,2,3,4,3,0,1,2,3,4,4,0,1,2,3,4]
但我需要这样:
[[0,0,0],[0,0,1],[0,0,2],[0,0,3],[0,0,4],[0,1,0],[0,1,1]...
有任何想法吗?
其他人已经回答了,但是您可能希望知道标准库中已经存在像您这样的函数:
> import Control.Monad
> replicateM 3 [0..4]
[[0,0,0],[0,0,1],[0,0,2],[0,0,3],[0,0,4],[0,1,0],[0,1,1], ...
因此,您希望最终列表的元素本身就是列表吗?
在List monad中,每个<-
从类型中删除一个封闭的内容,换句话说:
(x :: a) <- (xs :: [a])
因此很明显, x :: Int
在您的代码中。 并且您希望函数返回[[Int]]
那么x:(f (n-1))
的类型应该是什么? 你看,这个表达式应该不进行类型检查,如果f
所以你的问题类型是正确的:你不想利弊x
到的结果f (n-1)
但是每个结果的f (n-1)
因此:
f n = do
x <- [0..4]
xs <- f (n-1)
return (x : xs)
如果尝试这种方法,应该会发现它不起作用,这是因为f 0
应该包含一种可能性:
f 0 = return [] -- or [[]]
首先让我们脱糖:
f 0 = []
f n = [0 .. 4] >>= \x -> x : (f (n - 1)) >>= \y -> return y
注意
xs >>= f = concat (map f xs)
[0..4] >>= \\x -> x : (f (n - 1))
仅在n为1时返回[0..4]
。但是,它必须为[[0], [1], [2], [3], [4]]
,
因此,将执行以下操作:
f 0 = [[]]
f n = [0 .. 4] >>= \x -> map (x:) (f (n - 1)) >>= \y -> return y
cross = do
x <- [0..4]
y <- [0..4]
z <- [0..4]
return [x,y,z]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.