Haskell : Possible cause: ‘(:)’ is applied to too many arguments - haskell

I‘ve created a nested function which fails at the third nesting. I fail to understand why this pattern holds up for the previous two nests but not the third. I'm attempting to recursively work through the list to add the items in the list together
module Nests
(nest1,nest2,nest3) where
nest1 :: (Num a) => [a] -> [a] -> [a]
nest1 _ [] = []
nest1 [] _ = []
nest1 (xs:ls1) (xt:ls2) = (xs+xt):nest1 ls1 ls2
nest2 :: (Num a) => [[a]] -> [[a]] -> [[a]]
nest2 _ [] = []
nest2 [] _ = []
nest2 (xs:ls1) (xt:ls2) = (nest1 xs xt):nest2 ls1 ls2
nest3 :: (Num a) => [[[a]]] -> [[[a]]] -> [[[a]]]
nest3 (xs:xt:ls)
| length ls <= 0 = []
| otherwise = (nest2 xs xt):nest3 ls
where compiled:
nests.hs:17:19: error:
• Couldn't match expected type ‘[[[a]]] -> [[[a]]]’
with actual type ‘[[[a]]]’
• Possible cause: ‘(:)’ is applied to too many arguments
In the expression: (nest2 xs xt) : nest3 ls
In an equation for ‘nest3’:
nest3 (xs : xt : ls)
| length ls <= 0 = []
| otherwise = (nest2 xs xt) : nest3 ls
• Relevant bindings include
ls :: [[[a]]] (bound at nests.hs:15:14)
xt :: [[a]] (bound at nests.hs:15:11)
xs :: [[a]] (bound at nests.hs:15:8)
nest3 :: [[[a]]] -> [[[a]]] -> [[[a]]] (bound at nests.hs:15:1)
|
17 | | otherwise = (nest2 xs xt):nest3 ls
| ^^^^^^^^^^^^^^^^^^^^^^
nests.hs:17:33: error:
• Couldn't match expected type ‘[[[a]]]’
with actual type ‘[[[a]]] -> [[[a]]]’
• Probable cause: ‘nest3’ is applied to too few arguments
In the second argument of ‘(:)’, namely ‘nest3 ls’
In the expression: (nest2 xs xt) : nest3 ls
In an equation for ‘nest3’:
nest3 (xs : xt : ls)
| length ls <= 0 = []
| otherwise = (nest2 xs xt) : nest3 ls
• Relevant bindings include
ls :: [[[a]]] (bound at nests.hs:15:14)
xt :: [[a]] (bound at nests.hs:15:11)
xs :: [[a]] (bound at nests.hs:15:8)
nest3 :: [[[a]]] -> [[[a]]] -> [[[a]]] (bound at nests.hs:15:1)
|
17 | | otherwise = (nest2 xs xt):nest3 ls

Type annotation for nest3 does not match its body.
nest3 :: [[[a]]] -> [[[a]]] -> [[[a]]] means that function takes two arguments before returning list but in the function's body you take just one argument.
You can need to fix type signature (or just drop it, GHC is able to infer it):
nest3 :: (Num a) => [[[a]]] -> [[[a]]]
nest3 (xs:xt:ls)
| length ls <= 0 = []
| otherwise = (nest2 xs xt):nest3 ls
The problem here is that the first error seems not very relevant. The second one clearly states that nest3 expects one more argument.
• Couldn't match expected type ‘[[[a]]]’
with actual type ‘[[[a]]] -> [[[a]]]’
• Probable cause: ‘nest3’ is applied to too few arguments
But the first one suggest that (:) is used incorrectly.
• Couldn't match expected type ‘[[[a]]] -> [[[a]]]’
with actual type ‘[[[a]]]’
• Possible cause: ‘(:)’ is applied to too many arguments
To understand why there are two errors and why the first one is so obscure, consider how GHC works. It tries both to infer types and match inferred types with type annotations provided by the programmer.
Knowing that (:) :: b -> [b] -> [b] we can infer that nest3 ls must be of type [b] in the expression (..) : nest3 ls. Matching this with the provided type [[[a]]] -> [[[a]]] -> [[[a]]] gives the error ‘nest3’ is applied to too few arguments.
Trying to infer type of the otherwise branch in nest3 GHC considers again the type of (:). Applied to two arguments (:) gives a list. Matching this with the provided nest3 type gives ‘(:)’ is applied to too many arguments because only by removing one of the arguments we can get an arrow type.

Regarding the question of why it says ‘(:)’ is applied to too many arguments:
Since your type signature tells Haskell that the function takes two arguments, but you only match for one, it will interpret it as a function returning a function, kind of like in point free style
For example like this
plus :: Int -> Int -> Int
plus x = (+) x
which is equivalent to these
plus' :: Int -> Int -> Int
plus' x y = (+) x y
plus'' :: Int -> Int -> Int
plus'' = (+)
So, in this case, your function is equivalent to
nest3 :: (Num a) => [[[a]]] -> [[[a]]] -> [[[a]]]
nest3 (xs:xt:ls) z
| length ls <= 0 = [] z
| otherwise = ((nest2 xs xt):nest3 ls) z
-- or
-- | otherwise = (:) (nest2 xs xt) (nest3 ls) z
Which explains why it thinks (:) might be applied to too many arguments.

Related

Haskell Expected type: [t0 a0] Actual type: [a]

data PossibleTuple a = Multiple (a, Int) | Single a
pack :: (Eq a) => [a] -> [a]
{-
...
-}
encode_modified' :: (Eq a) => [a] -> [PossibleTuple a]
encode_modified' [] = []
encode_modified' x = map (\x -> element x) (pack x)
where
element x
| length x > 1 = Multiple (x, length x)
| otherwise = Single x
I'm trying to do this:
encodeModified "aaaabccaadeeee"
[Multiple 4 'a',Single 'b',Multiple 2 'c',
Multiple 2 'a',Single 'd',Multiple 4 'e']
but I get this error:
* Couldn't match type `a' with `t0 a0'
`a' is a rigid type variable bound by
the type signature for:
encode_modified' :: forall a. Eq a => [a] -> [PossibleTuple a]
at src/Lib.hs:117:1-54
Expected type: [t0 a0]
Actual type: [a]
* In the second argument of `map', namely `(pack x)'
In the expression: map (\ x -> element x) (pack x)
In an equation for encode_modified':
encode_modified' x
= map (\ x -> element x) (pack x)
where
element x
| length x > 1 = Multiple (x, length x)
| otherwise = Single x
* Relevant bindings include
x :: [a] (bound at src/Lib.hs:119:18)
encode_modified' :: [a] -> [PossibleTuple a]
(bound at src/Lib.hs:118:1)
|
119 | encode_modified' x = map (\x -> element x) (pack x)
| ^^^^^^
Why would pack x need to have the type t0 a0? x is of type a0 and thus pack x would have type [a0].
All the types seem to match. The output of the map function is PossibleTuple a0. I don't even know where the a0 t0 comes from.
What type do you suppose element has? You call length on its argument, meaning you think it takes a list as input. However, you also map it over a list of type [a], meaning you think it can take any type a as input. This is a type mismatch.
Similarly you say you hope that your result will look like [Multiple (4, 'a')], but your element function can never produce this result. The first element in each tuple is the length of the second element, and length 'a' is a type error.
The first thing I would do is re-examine the type of pack, though. It can't do anything with its current type that seems very relevant. Probably it should be Eq a => [a] -> [[a]]. After that you will have more type errors to resolve, leading to a better definition of element.
Multiple 4 'a'
This does not match the value constructor you defined. This is the constructor you defined
data PossibleTuple a = Multiple (a, Int) | Single a
So to construct Multiple, you should do Multiple ('a', 4). Conversely, if you want to do Multiple 4 'a', then your constructor should read
data PossibleTuple a = Multiple Int a | Single a
It should be pack :: Eq a => [a] -> [[a]].
This function already exists, it is called group. It groups together consecutive elements of a list, which are equal to one another.
Then element needs just a small tweak to work,
where
element x
| length x > 1 = Multiple (.... x, length x)
| otherwise = Single (.... x)
with the same name appearing on both ....s. Normally using that function is frowned upon but here it will be correct by construction.
Or you could use # patterns in pattern matching, like
where
element x#(h:_)
...........
This encoding is known as run-length encoding, in case you were wondering.
To easier see what's going on, it usually helps mentally if we name the lists by variables in plural, like using xs for a list of xs (xs is to be read like it rhymes with "axes"):
encode_modified' :: (Eq a) => [a] -> [PossibleTuple a]
encode_modified' [] = []
encode_modified' x = -- map (\x -> element x) (pack x)
map (\xs -> element xs) (pack x)
where
element xs
-- | length x > 1 = Multiple (x, length x) -- length of "x"??
| length xs > 1 = Multiple ( x , length xs) -- no, of "xs"!!
---
| otherwise = Single x
-----
and the (underscored) plurality type mis-matches are now self-evident.

Move One Element From one list to another In haskell

Morning i was doing an exercise it's my first time in Haskell
The exercise is to move the first element from my second list to the first position of my first list
Result: test [] [4,2,5,7]
=> ([4], [2,5,7])
That is my code :
test ::[a] -> [b] -> ([a],[b])
test [] [] = ([], [])
test [x] [] = ([x], [])
test [] [x] = ([x], [])
test [y] [x] = ([x:y], [])
But i got errors so please help me
this is my error
• Couldn't match expected type ‘[b]’ with actual type ‘a’
‘a’ is a rigid type variable bound by
the type signature for:
pa :: forall a b. [a] -> [b] -> ([a], [b])
at Pushswap.hs:30:6
• In the second argument of ‘(:)’, namely ‘y’
In the expression: x : y
In the expression: [x : y]
• Relevant bindings include
x :: b (bound at Pushswap.hs:34:9)
y :: a (bound at Pushswap.hs:34:5)
pa :: [a] -> [b] -> ([a], [b]) (bound at Pushswap.hs:31:1)
Failed, modules loaded: none.
In the implementation
test [y] [x] = ([x:y], [])
y is of type a, x is of type b and [x:y] needs to be of type [a], hence the error.
You should be able to get past this error by making both lists the same type.

Couldn't match expected type [Int] Haskell

I am new to Haskell so I don't quite understand most of its errors. I have encountered an error trying to make a higher order function that uses foldl() to read a list and then multiply it by 2 (it automatically reverses it) and I use another another foldl() just to read it, in so reversing it to its original order.
I would be thankful for any help I receive.
here's the error
• Couldn't match expected type ‘[Int]’
with actual type ‘t0 Integer -> [Integer]’
• Probable cause: ‘foldl’ is applied to too few arguments
In the first argument of ‘reverses’, namely
‘(foldl (\ acc x -> (2 * x) : acc) [])’
In the expression: reverses (foldl (\ acc x -> (2 * x) : acc) [])
In an equation for ‘multthr’:
multthr = reverses (foldl (\ acc x -> (2 * x) : acc) [])
|
16 | multthr = reverses(foldl(\acc x-> (2*x):acc)[])
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
here's the source code
reverses::[Int] ->[Int]
reverses = foldl(\acc x-> x:acc)[]
multthr::[Int]->([Int]->[Int])
multthr = reverses(foldl(\acc x-> (2*x):acc)[])
You need to compose your two foldl's with (.), instead of applying one to the other:
reverses :: [a] -> [a]
reverses = foldl (\acc x-> x:acc) []
---- multthr :: [Int] -> ([Int] -> [Int]) -- why??
multthr :: [Int] -> [Int]
---- multthr = reverses (foldl(\acc x-> (2*x):acc)[]) -- causes error
multthr = reverses . foldl (\acc x-> (2*x):acc) []
so that we have
> multthr [1..5]
[2,4,6,8,10]
it :: [Int]
(.) is the functional composition, defined as (f . g) x = f (g x).
Instead of doing the two foldl's you can do one foldr,
mult2 = foldr (\x r -> (2*x) : r) []
but then this is nothing else but, simply, map (2*).

Haskell add to list in list

i have the following code
groupEq :: Eq a => [a] -> [[a]]
groupEq list = foldl (\acc x -> if (isType acc x) then ((last acc) ++ [x]) else acc++[[x]]) [] list
isType :: Eq a => [[a]] -> a -> Bool
isType list item
| (length list) == 0 = False
| head (last list) == item = True
| otherwise = False
Now, i am having difficulties understanding why it would not compile.
The problem is with the ((last acc) ++ [x]) part of it. I understand it as it takes the last element of accumulator, which would be [[a]] at this point and tries to add an element to it.
The idea what i want to achieve is this:
-- groupEq [1,2,2,3,3,3,4,1,1] ==> [[1], [2,2], [3,3,3], [4], [1,1]]
Full error is
Couldn't match type ‘a’ with ‘[a]’
‘a’ is a rigid type variable bound by
the type signature for groupEq :: Eq a => [a] -> [[a]]
at exam_revisited.hs:3:12
Expected type: [[[a]]]
Actual type: [[a]]
Relevant bindings include
x :: a (bound at exam_revisited.hs:4:28)
acc :: [[a]] (bound at exam_revisited.hs:4:24)
list :: [a] (bound at exam_revisited.hs:4:9)
groupEq :: [a] -> [[a]] (bound at exam_revisited.hs:4:1)
In the first argument of ‘last’, namely ‘acc’
In the first argument of ‘(++)’, namely ‘(last acc)’
What am i missing here?
groupEq is declared to return [[a]], but ((last acc) ++ [x]) is of type [a].
A quick and dirty solution is to change this expression into
init acc ++ [last acc ++ [x]].

type error when compiling

I don't understand why the following code won't compile:
append :: [a] -> [a] -> [a]
append xs ys = foldr (:) ys xs
traverse :: a -> [a] -> [[a]]
traverse x [] = [[x]]
traverse x (y:ys) = append [(x:y:ys)] (map (y:) (traverse x ys))
comb :: [a] -> [[a]]
comb [] = [[]]
comb (x:[]) = [[x]]
comb (x:y:[]) = [[x,y],[y,x]]
comb (x:xs) = map (traverse x) (comb xs)
It produces the following error:
pr27.hs:13:20:
Couldn't match type `a' with `[a]'
`a' is a rigid type variable bound by
the type signature for comb :: [a] -> [[a]] at pr27.hs:10:1
Expected type: [a] -> [a]
Actual type: [a] -> [[a]]
In the return type of a call of `traverse'
In the first argument of `map', namely `(traverse x)'
Failed, modules loaded: none
But when I load just traverse and use it in an expression similar to the above, I get the desired result. What's going on?
Main> map (traverse 3) [[1,2],[2,1]]
[[[3,1,2],[1,3,2],[1,2,3]],[[3,2,1],[2,3,1],[2,1,3]]]
The problem is that comb has to return a value of type [[a]]. traverse returns a value of type [[a]], so mapping it over another list produces [[[a]]], which has too many levels of nesting.
Let's look at map. It has a type map :: (x -> y) -> [x] -> [y]. traverse x has a type [a] -> [[a]]. Now we need to combine the two. To do this, we replace x with [a] and y with [[a]], getting ([a] -> [[a]]) -> [[a]] -> [[[a]]]. This clearly shows the result of mapping traverse has to have at least three levels of nesting.
If you look at your example, this is what you actually get. For comb, you only want one two levels deep.
The reason your example worked in GHCi is because an expression there can have any type. Your map (traverse 3) [[1,2], [2,1]] expression is perfectly legal; however, it has the type Num a => [[[a]]], which is a list of lists of lists of numbers. (Try it: :t map (traverse 3) [[1,2], [2,3]].) However, the type of comb is [a] -> [[a]]. This means the result has to be a list of lists, not a list of lists of lists. So the issue is that map (traverse 3) is incompatible with comb, not that it is illegal by itself.

Resources