Haskell 使用列表monad实现每位数计数器
因此,我在研究这个问题,并为这个问题建立了一个相当丑陋的解决方案。在试图清理它的时候,我开始研究列表理解和列表单子。我决定使用列表monad实现一个每位数计数器。给定一个数字输入序列,Haskell 使用列表monad实现每位数计数器,haskell,list-comprehension,monads,Haskell,List Comprehension,Monads,因此,我在研究这个问题,并为这个问题建立了一个相当丑陋的解决方案。在试图清理它的时候,我开始研究列表理解和列表单子。我决定使用列表monad实现一个每位数计数器。给定一个数字输入序列,[1,2],我想生成一个输出序列,看起来像: [ [ 0, 0], [ 0, 1 ], [ 0, 2 ], [ 1, 0 ], [ 1, 1 ], [ 1, 2 ] ] 也就是说,我将迭代该范围内列表中所有元素的所有可能值 haskell.org说: 绑定函数应用于输入列表中的所有可能值,并将
[1,2]
,我想生成一个输出序列,看起来像:
[ [ 0, 0],
[ 0, 1 ],
[ 0, 2 ],
[ 1, 0 ],
[ 1, 1 ],
[ 1, 2 ] ]
也就是说,我将迭代该范围内列表中所有元素的所有可能值
haskell.org说:
绑定函数应用于输入列表中的所有可能值,并将结果列表连接起来以生成所有可能结果的列表
太好了!看起来很完美。。。以下是我为生成解决方案而编写的代码:
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)
计数::[Integer]->[[Integer]]
计数[]=[]
计数(x:xs)=
--获取剩余数字的所有可能序列
让
remDigits::[[Integer]]
remDigits=计数xs
在里面
--拉出剩余数字的可能顺序
do nextDigits首先,您需要单例列表的基本情况作为参数。试试这个:
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]
计数::[Integer]->[[Integer]]
计数[]=[]
计数[n]=map(\x->[x])[0..n]
计数(x:xs)=
多愁善感
是的,就这么简单。试试看:)为了完整起见,您还可以将逻辑表示为列表理解,这可能是将列表单子用于简单函数的最佳方式:
count (x:xs) = [ (y:ys) | y <- [0..x], ys <- count xs ]
count(x:xs)=[(y:ys)| y甚至更短
count = mapM (enumFromTo 0)
产生的结果与OP指定的结果不同!剩余的错误与我使用单子的顺序有关。如果您只需将基本大小写更改为count[]=[[],我应该有y
,这段代码很有效。实际上,这正是我想要的答案……我发现我的问题是,在基本情况下,单子列表中没有解决方案,因此没有任何东西可供构建。CBFraser下面的答案解决了这一问题,但你的解决方案更接近我最初的想法。哦,不确定我错过了sequence+map
到mapM
的机械翻译,但是明显的改进是+1:D
count = mapM (enumFromTo 0)