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.
Related
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.
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]].
Why this gives rigid type variable error:
data MyTree a = Leaf [a]
| Branch (String, a) [MyTree a]
deriving (Show)
list :: MyTree a -> [a]
list (Leaf []) = []
list (Leaf m) = m
list (Branch _ (x:xs)) = list x ++ map (list) xs
-------------------------------------------------------------
Couldn't match type `a' with `[a]'
`a' is a rigid type variable bound by
the type signature for list :: MyTree a -> [a]
at test.hs:6:15
Expected type: MyTree a -> a
Actual type: MyTree a -> [a]
In the first argument of `map', namely `(list)'
In the second argument of `(++)', namely `map (list) xs'
In the expression: list x ++ map (list) xs
The part of the error that actually tells you what is happening is:
Expected type: MyTree a -> a
Actual type: MyTree a -> [a]
In the first argument of `map', namely `(list)'
So the type of the function you give to map is wrong. But why is it so? map has type:
map :: (a -> b) -> [a] -> [b]
list is MyTree a -> [a], and therefore:
map list :: (MyTree a -> [a]) -> [MyTree a] -> [[a]]
That means map list xs will have type [[a]]. You are using it like this:
list x ++ map list xs -- omitting unnecessary parentheses.
(++) is list concatenation; it expects two lists of the same type. list x, however, is [a] instead of [[a]], which leads to the type error. Since [a] is the type of an element of [[a]], you might try using (:), instead of (++), to prepend list x to the rest of your list-of-lists.
list (Branch _ (x:xs)) = list x : map list xs
That, however, is redundant: you are applying the same list function to x and the elements of xs. That means you can simplify it to:
list (Branch _ xs) = map list xs
We are still not done, as map list xs has type [[a]], and you want [a]. That is easy to solve, though: just use concatMap, which maps the function and flattens the resulting list-of-lists. The full definition would then become:
list :: MyTree a -> [a]
list (Leaf m) = m
list (Branch _ xs) = concatMap list xs
I have removed the redundant (Leaf []) case. Note that your function did not cover the (
Branch _ []) case; that's not a problem now that we are not matching (x:xs) only.
The type of map (list) xs is [[a]] and you want something of type [a]. There is a function concat that we can use: concat (map list xs), but we can write it more idiomatically with concatMap: concatMap list xs
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.
selectMenu :: Int->IO()
selectMenu num
|(num==1)=convertFromDecimal
|(num==2)=--menu2
|(num==3)=putStrLn("3")
|(num==4)=putStrLn("4")
|(num==5)=putStrLn("5")
convertFromDecimal:: IO()
convertFromDecimal= do
putStrLn("\n\tConvert From Decimal To Binary & Octals \n")
putStrLn("----------------------------------------------------------\n")
putStrLn("Enter 5 decimal numbers [,,] : ")
input<-getLine
let n=(read input)::[Int] -- is this right?
--putStrLn (show n)
let result = convertionTO decToOct n
putStrLn(show result)`
decToOct :: Int -> [Int]
decToOct x = reverse(decToOct' x)
where
decToOct' 0 = []
decToOct' y = let (a,b) = quotRem y 8 in [b] ++ decToOct' a
convertionTO :: (Int -> [Int] -> [Int]) -> [Int] -> [Int]
convertionTO _ [] = []
convertionTO f (x:xs) = f x : convertionTO f xs
I correct those mistakes. I did update the question after correcting those errors. But this time it gives this error
How can i fix this error?
Assignment.hs:49:51:
Couldn't match expected type `[Int] -> [Int]'
with actual type `[Int]'
Expected type: Int -> [Int] -> [Int]
Actual type: Int -> [Int]
In the first argument of `convertionTO', namely `decToOct'
In the expression: convertionTO decToOct n
Assignment.hs:66:25:
Couldn't match expected type `Int'
with actual type `[Int] -> [Int]'
In the return type of a call of `f'
In the first argument of `(:)', namely `f x'
In the expression: f x : convertionTO f xs
(I'm copying the errors here in case you edit the question again.)
The first error
Assignment.hs:49:51:
Couldn't match expected type `[Int] -> [Int]'
with actual type `[Int]'
Expected type: Int -> [Int] -> [Int]
Actual type: Int -> [Int]
In the first argument of `convertionTO', namely `decToOct'
In the expression: convertionTO decToOct n
refers to this line of code
let result = convertionTO decToOct n
conversionTO expects its first argument to have the type Int -> [Int] -> [Int], but decToOct instead has the type Int -> [Int].
The second error
Assignment.hs:66:25:
Couldn't match expected type `Int'
with actual type `[Int] -> [Int]'
In the return type of a call of `f'
In the first argument of `(:)', namely `f x'
In the expression: f x : convertionTO f xs
refers to this line of code
convertionTO f (x:xs) = f x : convertionTO f xs
convertionTO produces an [Int], so the first argument to : must be an Int. But f x instead has type [Int] -> [Int].
How to fix these?
I'm going to assume that your line 49 is correct, and that the type signature for convertionTO is wrong. In that case it should be
convertionTO :: (Int -> [Int]) -> [Int] -> [Int]
This doesn't fix the second error, as f x now has type [Int].
The problem here is your use of :. : joins a single element to the start of a list. What you have is two lists that you want to join together. For this, use ++.
convertionTO f (x:xs) = f x ++ convertionTO f xs
Finally, note that your convertionTO is in the standard library as concatMap, which combines map with concat.
Those errors mean that you're referring to functions which don't exist. Either because you mistyped their names, or because you haven't defined them yet.
For example, instead of showresult, you probably meant show result, and I think you meant decToOct' instead of decToAny'. I can't see any references to convertToDecimal anywhere in the code you posted, so that error is probably somewhere else.