Haskell根据给定的输入创建一个n元组

Ole*_*eit 3 haskell list

说实话,我对Haskell很新,试图解决问题(编程练习)我过来了.它说我应该创建一个函数

com :: Int -> [t] -> [[t]]
Run Code Online (Sandbox Code Playgroud)

返回n个元素的所有可能选择,其中n和list分别是第一个和第二个参数.可以以不同的顺序再次拾取元素.结果如下:

com 2 [1,2,3] = [[1,1], [1,2]..[3,3]]
Run Code Online (Sandbox Code Playgroud)

对于n = 1和n = 2的情况,我设法解决了这些情况.情况n = 1非常简单,对于n = 2的情况,我会使用连接并构建它.但是,我不明白它是如何成为n-ary并为所有人工作的.就像突然一个函数调用会像com 10...

chi*_*chi 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"]
Run Code Online (Sandbox Code Playgroud)

以上利用了sequence列表monad中构建列表列表的笛卡尔积的事实.因此,我们可以简单地复制列表n时间,然后获取产品.

(注意"abc"上面是charatcters列表的简写['a','b','c'])

所以,解决方案可能是

com n xs = sequence (replicate n xs)
Run Code Online (Sandbox Code Playgroud)

或等效地,正如Daniel Wagner在下面指出的,

com = replicateM
Run Code Online (Sandbox Code Playgroud)

最后一点:我确实意识到这对于实际学习如何编程可能没什么帮助.实际上,我从库中提取了两个"神奇"功能来解决任务.不过,它显示了如何将问题简化为两个子问题:1)复制值n时间和2)构建笛卡尔积.如果您不想使用该库,第二项任务本身就是一项很好的练习.您可能希望从以下开始解决:

sequence :: [[a]] -> [[a]]
sequence []     = [[]]
sequence (x:xs) = ...
       where ys = sequence xs
Run Code Online (Sandbox Code Playgroud)

  • `replicateM n =序列.复制n` (2认同)