Reputation: 587
I have the following code in haskell and I get
[[a0]] -> [a0]' with
[Int]'
Expected type: [Int] -> [Int]
Actual type: [Int] -> [[a0]] -> [a0]Code:
findlist:: [[Int]] -> [Int]
findlist (l1, l2, l3, l4, l5) = do 1)
let n = length l1
e1 <- [1..n]
e2 <- [1..n]
e3 <- [1..n]
e4 <- [1..n]
e5 <- [1..n]
let list1 = pick_list $ myperms e1 l1 --here
list2 = pick_list $ myperms e2 l2 --here
list3 = pick_list $ myperms e3 l3 --here
list4 = pick_list $ myperms e4 l4 --here
list5 = pick_list $ myperms e5 l5 --here
guard $ all (== list1) $ [list2, list3, list4, list5]
guard $ e1 `notElem` [e2, e3, e4, e5]
guard $ e2 `notElem` [e3, e4, e5]
guard $ e3 `notElem` [e4, e5]
guard $ e4 `notElem` [e5]
return concat list1 2)
Type signatures:
pick_list:: [[Int]] -> [Int]
myperms:: Int -> [Int] -> [[Int]]
What's wrong with it and how can I realize when I'm gonna get such errors? Thanks in advance.
Upvotes: 0
Views: 266
Reputation: 54058
Your where
clause needs to be indented underneath findlist
. However, this code has more problems than just that.
The first big problem I see is that you're getting particular elements of list
, but you haven't ensured that it has at least 5 elements. Maybe you should be passing in a tuple instead?
Second, you reference elem1
, elem2
, etc in the where clause, but they aren't in scope outside of the list comprehension, they can't be used outside of the square brackets.
Third is that your comprehension will return copies of list1
, one for each successful match in your huge list comprehension condition. Even if it could compile, I don't think this code would do what you want it to.
You could instead write this in a monadic form. I've taken the liberty of simplifying your checks using Control.Monad.guard
as well and getting rid of elements
:
findlist (l1, l2, l3, l4, l5) = do
let n = length l1
e1 <- [1..n]
e2 <- [1..n]
e3 <- [1..n]
e4 <- [1..n]
e5 <- [1..n]
let list1 = pick_list $ myperms e1 l1
list2 = pick_list $ myperms e2 l2
list3 = pick_list $ myperms e3 l3
list4 = pick_list $ myperms e4 l4
list5 = pick_list $ myperms e5 l5
guard $ all (== list1) [list2, list3, list4, list5]
guard $ e1 `notElem` [e2, e3, e4, e5]
guard $ e2 `notElem` [e3, e4, e5]
guard $ e3 `notElem` [e4, e5]
guard $ e4 `notElem` [e5]
return list1
This code is certainly a lot easier to read, and it will have equivalent performance (which will be slow for large n
)
Upvotes: 1