Haskell:Monad返回列表

时间:2015-05-24 14:55:57

标签: haskell monads

我正在尝试在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]...

有什么想法吗?

4 个答案:

答案 0 :(得分:4)

其他人已经回答了,但您可能希望知道标准库中已有类似您的功能:

> 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], ...

答案 1 :(得分:3)

所以你希望最终列表中的元素自己列出?

在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 [[]] 应该包含一种可能性:

myFtf.setValue(null);

答案 2 :(得分:2)

让我们首先去除药物:

f 0 = []
f n = [0 .. 4] >>= \x -> x : (f (n - 1)) >>= \y -> return y

请注意

xs >>= f = concat (map f xs)
当n为1时,

[0..4] >>= \x -> x : (f (n - 1))只会返回[0..4]。但是,它必须是[[0], [1], [2], [3], [4]]

因此,以下将做:

f 0 = [[]]
f n = [0 .. 4] >>= \x -> map (x:) (f (n - 1)) >>= \y -> return y

答案 3 :(得分:0)

cross = do
x <- [0..4]
y <- [0..4]
z <- [0..4]
return [x,y,z]