algorithm - infinite type error in haskell when trying to translate python function into haskell. Why? -
def get_n_partition_permutations(xs, n): if n == 1: return [[xs]] acc = [] in xrange(1,len(xs)): acc += [[xs[:i]] + j j in get_n_partition_permutations(xs[i:], n-1)] return acc
i'm trying implement function above (which in python) in haskell below.
getnpartitionpermutations :: [a] -> int -> [[[a]]] getnpartitionpermutations xs 1 = [[xs]] getnpartitionpermutations xs n = iter xs 1 [] iter ys acc | length xs == = acc | otherwise = iter ys (i+1) (elem':acc) elem' = map (\x -> [(take ys)]:x) rec' rec' = getnpartitionpermutations (drop ys) (n-1)
i'm getting strange error don't understand. why code work in python not in haskell? error message below
partitionarr.hs|23 col 104 error| occurs check: cannot construct infinite type: ~ [[a]] expected type: [[[a]]] actual type: [a] relevant bindings include acc :: [[[[[a]]]]] (bound @ partitionarr.hs:21:19) ys :: [a] (bound @ partitionarr.hs:21:14) iter :: [a] -> ghc.types.int -> [[[[[a]]]]] -> [[[[[a]]]]] (bound @ partitionarr.hs:21:9) xs :: [[[a]]] (bound @ partitionarr.hs:20:27) getnpartitionpermutations :: [[[a]]] -> ghc.types.int -> [[[[[a]]]]] (bound @ partitionarr.hs:19:1) in first argument of ‘algo.getnpartitionpermutations’, namely ‘(ghc.list.drop n ys)’ in 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 infinite type: ~ [[a]] expected type: [a] actual type: [[[a]]] relevant bindings include iter :: [a] -> ghc.types.int -> [[[[[a]]]]] -> [[[[[a]]]]] (bound @ partitionarr.hs:21:9) xs :: [[[a]]] (bound @ partitionarr.hs:20:27) getnpartitionpermutations :: [[[a]]] -> ghc.types.int -> [[[[[a]]]]] (bound @ partitionarr.hs:19:1) in first argument of ‘iter’, namely ‘xs’in expression: iter xs 1 []
edit: because wasn't clear. python function return possible n partitions of list. parameters [1,2,3,4],2 gives [[[1],[2,3,4]],[[1,2],[3,4]],[[1,2,3][4]]]
type signature of haskell function [a] -> int -> [[[a]]]
first of all, i've made haskell code little bit more comprehensible:
getnpartitionpermutations :: [a] -> int -> [[[a]]] getnpartitionpermutations xs 1 = [[xs]] getnpartitionpermutations xs n = iter xs 1 [] iter ys n acc | length xs == n = acc | otherwise = iter ys (n+1) (elem:acc) elem = map (\x -> [(take n ys)]:x) rec' rec' = getnpartitionpermutations (drop n ys) (n-1)
it looks type problem coming expression in definition of elem
:
[(take n ys)]:x
if replace head x
or take n ys
or take n ys ++ x
, code compiles. indicates somehow providing value of type [[[a]]]
instead of value of type [a]
. is, have 2 wrappings []
.
and whereas didn't take time understand code meant do, i'm quite sure given these hints can figure out problem is.
edit: problem use of :
instead of ++
, unnecessary wrapping in [take n ys]
, replacing take n ys ++ x
way go. (just incorporating comments answer)
general advice:
the way go tracking down/pinpointing type errors first refactoring code way did, i.e. splitting large expressions , giving names subexpressions meanings become more visible , temporarily replace parts of overall expression undefined
, because undefined
has type , allows code compile without having figure out of in 1 go. example, ended before trying head x
, take n ys
(note (\x -> undefined)
bit):
getnpartitionpermutations :: [a] -> int -> [[[a]]] getnpartitionpermutations xs 1 = [[xs]] getnpartitionpermutations xs n = iter xs 1 [] iter ys n acc | length xs == n = acc | otherwise = iter ys (n+1) (elem:acc) elem = map (\x -> undefined) rec' rec' = getnpartitionpermutations (drop n ys) (n-1)
— largest subset of original code still compiled.
and before that, had:
getnpartitionpermutations :: [a] -> int -> [[[a]]] getnpartitionpermutations xs 1 = [[xs]] getnpartitionpermutations xs n = iter xs 1 [] iter ys n acc = undefined
after gradually started reintroducing original bits, moving undefined
bit further down code tree:
getnpartitionpermutations :: [a] -> int -> [[[a]]] getnpartitionpermutations xs 1 = [[xs]] getnpartitionpermutations xs n = iter xs 1 [] iter ys n acc | length xs == n = acc | otherwise = undefined
then
getnpartitionpermutations :: [a] -> int -> [[[a]]] getnpartitionpermutations xs 1 = [[xs]] getnpartitionpermutations xs n = iter xs 1 [] iter ys n acc | length xs == n = acc | otherwise = iter ys (n+1) (elem:acc) elem = undefined rec' = undefined
and on.
Comments
Post a Comment