说得好,我对Haskell很新,试图解决问题(编程练习)我过来了。它说我应该创建一个函数
com :: Int -> [t] -> [[t]]
返回n个元素的所有可能选择,其中n和list分别是第一个和第二个参数。可以以不同的顺序再次拾取元素。结果就像:
com 2 [1,2,3] = [[1,1], [1,2]..[3,3]]
对于n = 1和n = 2的情况,我设法解决了这些情况。情况n = 1非常简单,对于n = 2的情况,我会使用连接并构建它。但是,我不明白它是如何成为n-ary并为所有人工作的。就像突然一个函数调用会像com 10
...
答案 0 :(得分:5)
这是你想要的吗?
> sequence (replicate 3 "abc")
["aaa","aab","aac","aba","abb","abc","aca","acb","acc"
,"baa","bab","bac","bba","bbb","bbc","bca","bcb","bcc"
,"caa","cab","cac","cba","cbb","cbc","cca","ccb","ccc"]
以上内容利用了列表monad中sequence
构建列表列表的笛卡尔积的事实。因此,我们可以简单地复制列表n
次,然后获取产品。
(请注意,上面"abc"
是charatcters列表的简写['a','b','c']
)
所以,解决方案可能是
com n xs = sequence (replicate n xs)
或等效地,正如Daniel Wagner在下面指出的那样,
com = replicateM
最后一点:我确实意识到这对于实际学习如何编程可能不是很有帮助。实际上,我从库中提取了两个“神奇”功能来解决任务。不过,它还显示了如何将问题简化为两个子问题:1)复制值n
次和2)构建笛卡尔积。如果您不想使用该库,第二项任务本身就是一项很好的练习。您可能希望从以下开始解决这个问题:
sequence :: [[a]] -> [[a]]
sequence [] = [[]]
sequence (x:xs) = ...
where ys = sequence xs
答案 1 :(得分:2)
首先:[]
是列表构造函数,而不是元组。我不知道建立n元组元的任何一般方法。
但是,坚持列表,如果您已解决n = 1
案例并解决了n = 2
案例,请尝试用前者表达后者。然后根据n
:
n-1
com n xs = concat [map (x:) (com (n-1) xs) | x <- xs ]
答案 2 :(得分:1)
更简洁的编写方式,但在尝试理解List
非确定性并试图准确理解Haskell理解语法糖的真正含义时,可能更有用的是用do
来编写符号:
com :: Int -> [a] -> [[a]]
com 0 _ = []
com 1 xs = [[x] | x <- xs]
com n xs = do
x <- xs
let ys = com (n - 1) xs
map (x:) ys