【发布时间】:2015-09-30 08:27:34
【问题描述】:
def get_N_Partition_Permutations(xs, n):
if n == 1:
return [[xs]]
acc = []
for i in xrange(1,len(xs)):
acc += [[xs[:i]] + j for j in get_N_Partition_Permutations(xs[i:], n-1)]
return acc
我正在尝试在下面的 haskell 中实现上面的函数(在 Python 中)。
getNPartitionPermutations :: [a] -> Int -> [[[a]]]
getNPartitionPermutations xs 1 = [[xs]]
getNPartitionPermutations xs n = iter xs 1 []
where iter ys i acc
| length xs == i = acc
| otherwise =
iter ys (i+1) (elem':acc)
where elem' = map (\x -> [(take i ys)]:x) rec'
rec' = getNPartitionPermutations (drop i ys) (n-1)
我遇到了一个我不完全理解的奇怪错误。为什么这段代码在 python 中有效,但在 haskell 中无效?错误信息如下
partitionArr.hs|23 col 104 error| Occurs check: cannot construct the infinite type: a ~ [[a]]
Expected type: [[[a]]]
Actual type: [a]
Relevant bindings include
acc :: [[[[[a]]]]] (bound at partitionArr.hs:21:19)
ys :: [a] (bound at partitionArr.hs:21:14)
iter :: [a] -> GHC.Types.Int -> [[[[[a]]]]] -> [[[[[a]]]]] (bound at partitionArr.hs:21:9)
xs :: [[[a]]] (bound at partitionArr.hs:20:27)
getNPartitionPermutations :: [[[a]]] -> GHC.Types.Int -> [[[[[a]]]]]
(bound at partitionArr.hs:19:1)
In the first argument of ‘Algo.getNPartitionPermutations’,
namely ‘(GHC.List.drop n ys)’
In the second argument of ‘(GHC.Base.$!)’,
namely ‘Algo.getNPartitionPermutations (GHC.List.drop n ys) (n
GHC.Num.- 1)’
partitionArr.hs|20 col 39 error| Occurs check: cannot construct the infinite type: a ~ [[a]]
Expected type: [a]
Actual type: [[[a]]]
Relevant bindings include
iter :: [a] -> GHC.Types.Int -> [[[[[a]]]]] -> [[[[[a]]]]] (bound at partitionArr.hs:21:9)
xs :: [[[a]]] (bound at partitionArr.hs:20:27)
getNPartitionPermutations :: [[[a]]] -> GHC.Types.Int -> [[[[[a]]]]]
(bound at partitionArr.hs:19:1)
In the first argument of ‘iter’, namely ‘xs’In the expression: iter xs 1 []
编辑:因为我不清楚。 python 函数所做的是返回列表的所有可能的 n 分区。所以参数 [1,2,3,4],2 给出 [[[1],[2,3,4]],[[1,2],[3,4]],[[1,2,3 ][4]]]
haskell 函数的类型签名是 [a] -> Int -> [[[a]]]
【问题讨论】:
-
消息说您的列表嵌套级别不匹配。尝试向您的函数添加显式类型签名;那么 GHC 就会知道您打算的类型是什么,并且可能能够让您更好地了解错误在哪里。
-
我个人的理论是你不需要
map (\x -> [(take n ys)]:x)中的方括号,但我没有检查过。 -
仅作记录:您的 Python 代码中缺少
subdivideList的定义。 -
啊我错了,这是一个递归调用。