所以,我正在研究问题here,并针对这个问题构建了一个相当丑陋的解决方案。在尝试清理时,我开始调查列表推导和列表monad。我决定要做的是使用list monad实现一个每位数的计数器。给定一个数字输入序列[1, 2]
,我想生成一个类似于:
[ [ 0, 0],
[ 0, 1 ],
[ 0, 2 ],
[ 1, 0 ],
[ 1, 1 ],
[ 1, 2 ] ]
也就是说,我会遍历该范围内列表中所有元素的所有可能值。
haskell.org list monad documentation说:
绑定函数应用于输入列表中的所有可能值,并将结果列表连接起来以生成所有可能结果的列表。
大!看起来很完美......这是我为编写解决方案而编写的代码:
count :: [Integer] -> [[Integer]]
count [] = []
count (x:xs) =
-- get all possible sequences for the remaining digits
let
remDigits :: [[Integer]]
remDigits = count xs
in
-- pull out a possible sequence for the remaining digits
do nextDigits <- remDigits
-- pull out all possible values for the current digit
y <- [0..x]
-- record that "current digit" : "remaining digits" is
-- a valid output.
return (y:nextDigits)
但是用任何东西调用count
会产生空列表,我不知道为什么。我错过了什么?
答案 0 :(得分:8)
count = sequence . map (enumFromTo 0)
是的,它真的很简单。试一试:)
答案 1 :(得分:8)
更短
count = mapM (enumFromTo 0)
答案 2 :(得分:3)
为了完整性,您还可以将逻辑表达为列表理解,这可能是使用list monad进行简单函数的最佳方法:
count (x:xs) = [ (y:ys) | y <- [0..x], ys <- count xs ]
答案 3 :(得分:2)
首先,您需要将单例列表作为参数的基本案例。试试这个:
count :: [Integer] -> [[Integer]]
count [] = []
count [n] = map (\x -> [x]) [0..n]
count (x:xs) =
do y <- [0..x]
nextDigits <- count xs
return (y:nextDigits)
main = do
print $ count [1]
print $ count [1,2]