Couldn't match expected type ‘[Int]’ with actual type ‘Int’ haskell - haskell

I'm trying to do an exercise that gives a list of every path of a binary tree from leaf to root
here's my code:
data Tree = Leaf Int | Node (Tree) Int (Tree)
go (Leaf a) = (a : []) : []
go (Node l n r) = insev((go l):(go r)) n
insev :: [[a]] -> a -> [[a]]
insev [[]] x = []
insev (h:t) x = (insb h x) : (insev t x)
insb [] num = num : []
insb (h:t) num = h:(insb t num)
it should be correct from logical perspective but i am new to haskell and i don't know why i get this error
Main.hs:21:19: error:
• Couldn't match type ‘[Int]’ with ‘Int’
Expected: [[Int]]
Actual: [[[Int]]]
• In the expression: insev ((go l) : (go r)) n
In an equation for ‘go’:
go (Node l n r) = insev ((go l) : (go r)) n
|
21 | go (Node l n r) = insev ((go l):(go r)) n
| ^^^^^^^^^^^^^^^^^^^^^^^
Main.hs:21:34: error:
• Couldn't match type ‘Int’ with ‘[Int]’
Expected: [[[Int]]]
Actual: [[Int]]
• In the second argument of ‘(:)’, namely ‘(go r)’
In the first argument of ‘insev’, namely ‘((go l) : (go r))’
In the expression: insev ((go l) : (go r)) n
|
21 | go (Node l n r) = insev ((go l):(go r)) n
| ^^^^
Main.hs:21:41: error:
• Couldn't match expected type ‘[Int]’ with actual type ‘Int’
• In the second argument of ‘insev’, namely ‘n’
In the expression: insev ((go l) : (go r)) n
In an equation for ‘go’:
go (Node l n r) = insev ((go l) : (go r)) n
|
21 | go (Node l n r) = insev ((go l):(go r)) n

Without even looking at the rest of the code, this is never* going to fly:
(go l) : (go r)
Presumably go is returning something of the same type in both calls, but the arguments to (:) must have different types:
(:) :: a -> [a] -> [a]
Perhaps you want (++) instead, whose arguments must have the same types:
(++) :: [a] -> [a] -> [a]
* Okay, yes, it is possible to write go in a way that invalidates the next sentence's assumption that it is returning the same type in both calls. But that's a pretty unusual situation to be in, and one you have to pretty consciously try to arrive at.

Related

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 split function for multi-character delimeter

I've seen this code for the split function in Haskell already:
split :: String -> [String]
split [] = [""]
split (c:cs)
| c == ',' = "" : (split cs)
| otherwise = (c : head (split cs)) : tail (split cs)
Sample: Input: "1,2,3" Output:["1","2","3"]
However, this code only works when the delimeter is a ','. The code could be changed easily like this:
split :: Char->String -> [String]
split [] = [""]
split d (c:cs)
| c == d = "" : (split cs)
| otherwise = (c : head (split cs)) : tail (split cs)
So that the function works for any single character as the delimeter.
However, I want a function that works when the delimeter is a string itself.
So, I've tried this:
split' :: String -> String -> [String]
split' (d:ds) (c:cs)
| (d:ds) `isPrefixOf'` (c:cs) = "":rest
| otherwise = (c:head(split'((d:ds),rest))):tail(split'((d:ds),rest))
where
rest = split' (d:ds) drop( length(d:ds) (c:cs) )
where
isPrefixOf' :: (Eq a) => [a] -> [a] -> Bool
isPrefixOf' [] _ = True
isPrefixOf' _ [] = False
isPrefixOf' (x:xs) (y:ys)= (x == y) && (isPrefixOf' xs ys)
However, I get this ugly error when I load the program:
Prelude> :l testingsplit.hs
[1 of 1] Compiling Main ( testingsplit.hs, interpreted )
testingsplit.hs:15:27: error:
• Couldn't match expected type ‘[[Char]]’
with actual type ‘String -> [String]’
• Probable cause: ‘split'’ is applied to too few arguments
In the first argument of ‘head’, namely ‘(split' ((d : ds), rest))’
In the second argument of ‘(:)’, namely
‘head (split' ((d : ds), rest))’
In the first argument of ‘(:)’, namely
‘(c : head (split' ((d : ds), rest)))’
|
15 | | otherwise = (c:head(split'((d:ds),rest))):tail(split'((d:ds),rest))
| ^^^^^^^^^^^^^^^^^^^
testingsplit.hs:15:33: error:
• Couldn't match type ‘([Char], b0)’ with ‘[Char]’
Expected type: String
Actual type: ([Char], b0)
• In the first argument of ‘split'’, namely ‘((d : ds), rest)’
In the first argument of ‘head’, namely ‘(split' ((d : ds), rest))’
In the second argument of ‘(:)’, namely
‘head (split' ((d : ds), rest))’
|
15 | | otherwise = (c:head(split'((d:ds),rest))):tail(split'((d:ds),rest))
| ^^^^^^^^^^^^^
testingsplit.hs:15:54: error:
• Couldn't match expected type ‘[[Char]]’
with actual type ‘String -> [String]’
• Probable cause: ‘split'’ is applied to too few arguments
In the first argument of ‘tail’, namely ‘(split' ((d : ds), rest))’
In the second argument of ‘(:)’, namely
‘tail (split' ((d : ds), rest))’
In the expression:
(c : head (split' ((d : ds), rest)))
: tail (split' ((d : ds), rest))
|
15 | | otherwise = (c:head(split'((d:ds),rest))):tail(split'((d:ds),rest))
| ^^^^^^^^^^^^^^^^^^^
testingsplit.hs:15:60: error:
• Couldn't match type ‘([Char], b1)’ with ‘[Char]’
Expected type: String
Actual type: ([Char], b1)
• In the first argument of ‘split'’, namely ‘((d : ds), rest)’
In the first argument of ‘tail’, namely ‘(split' ((d : ds), rest))’
In the second argument of ‘(:)’, namely
‘tail (split' ((d : ds), rest))’
|
15 | | otherwise = (c:head(split'((d:ds),rest))):tail(split'((d:ds),rest))
| ^^^^^^^^^^^^^
testingsplit.hs:17:13: error:
• Couldn't match expected type ‘t0 -> t’
with actual type ‘[String]’
• The function ‘split'’ is applied to three arguments,
but its type ‘String -> String -> [String]’ has only two
In the expression: split' (d : ds) drop (length (d : ds) (c : cs))
In an equation for ‘rest’:
rest = split' (d : ds) drop (length (d : ds) (c : cs))
• Relevant bindings include
rest :: t (bound at testingsplit.hs:17:6)
|
17 | rest = split' (d:ds) drop( length(d:ds) (c:cs) )
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
testingsplit.hs:17:27: error:
• Couldn't match type ‘Int -> [a0] -> [a0]’ with ‘[Char]’
Expected type: String
Actual type: Int -> [a0] -> [a0]
• Probable cause: ‘drop’ is applied to too few arguments
In the second argument of ‘split'’, namely ‘drop’
In the expression: split' (d : ds) drop (length (d : ds) (c : cs))
In an equation for ‘rest’:
rest = split' (d : ds) drop (length (d : ds) (c : cs))
|
17 | rest = split' (d:ds) drop( length(d:ds) (c:cs) )
| ^^^^
testingsplit.hs:17:33: error:
• Couldn't match expected type ‘[Char] -> t0’
with actual type ‘Int’
• The function ‘length’ is applied to two arguments,
but its type ‘[Char] -> Int’ has only one
In the third argument of ‘split'’, namely
‘(length (d : ds) (c : cs))’
In the expression: split' (d : ds) drop (length (d : ds) (c : cs))
|
17 | rest = split' (d:ds) drop( length(d:ds) (c:cs) )
| ^^^^^^^^^^^^^^^^^^^
Failed, no modules loaded.
I don't understand where I have gone wrong.
Also, I already know Data.List has the splitOn method, which does this already. However, I am not allowed to use that module for the work I am doing. I am only interested in answers that only use Haskell's Data.Char and the Prelude.
I have a follow-up question: How could I change split' so it works for any type of list in general. I'm not fully sure what type signature I should use.
I've tried this:
split'' :: Eq a => [a] -> [a] -> [[a]]
split'' _ [] = []
split'' [] x = map (:[]) x
split'' a#(d:ds) b#(c:cs)
| Just suffix <- a `stripPrefix'` b = "":split'' a suffix
| otherwise = if null rest
then [[c]]
else (c:head rest):tail rest
where
rest = split'' a $ tail b
stripPrefix' :: Eq a => [a] -> [a] -> Maybe [a]
stripPrefix' [] ys = Just ys
stripPrefix' (x:xs) (y:ys)
| x == y = stripPrefix' xs ys
stripPrefix' _ _ = Nothing
Now, I get this error about the Char type when I load the program:
[1 of 1] Compiling Main ( splittest.hs, interpreted )
splittest.hs:24:46: error:
• Couldn't match type ‘a’ with ‘Char’
‘a’ is a rigid type variable bound by
the type signature for:
split'' :: forall a. Eq a => [a] -> [a] -> [[a]]
at splittest.hs:20:1-38
Expected type: [[Char]]
Actual type: [[a]]
• In the second argument of ‘(:)’, namely ‘split'' a suffix’
In the expression: "" : split'' a suffix
In an equation for ‘split''’:
split'' a#(d : ds) b#(c : cs)
| Just suffix <- a `stripPrefix'` b = "" : split'' a suffix
| otherwise
= if null rest then [[c]] else (c : head rest) : tail rest
where
rest = split'' a $ tail b
• Relevant bindings include
suffix :: [a] (bound at splittest.hs:24:12)
rest :: [[a]] (bound at splittest.hs:29:7)
cs :: [a] (bound at splittest.hs:23:23)
c :: a (bound at splittest.hs:23:21)
b :: [a] (bound at splittest.hs:23:18)
ds :: [a] (bound at splittest.hs:23:14)
(Some bindings suppressed; use -fmax-relevant-binds=N or -fno-max-relevant-binds)
|
24 | | Just suffix <- a `stripPrefix'` b = "":split'' a suffix
| ^^^^^^^^^^^^^^^^^
Failed, no modules loaded.
I'm new to Haskell, so I don't know where I have made a mistake.
Also, thank you for your earlier reply. It was very helpful and detailed.
Your code has many things wrong with it, including bad spacing and repetition of (d:ds) and (c:cs) when you could just give the whole thing a name by taking a#(d:ds) as an argument. However, these are all just stylistic errors. The biggest error in your code is the fact that you're trying to call functions like python, where it's the function name followed by parentheses followed by a comma separated list of arguments. Haskell does not work like this. Function arguments are separated by spaces, and you don't need parentheses after the function call. If you comma-separate arguments, you just create a tuple and call the function on that tuple, which breaks the whole thing. Here's your cleaned up code:
split' :: String -> String -> [String]
split' a#(d:ds) b#(c:cs)
| a `isPrefixOf'` b = "":rest
| otherwise = (c:head (split' a rest)):tail (split' a rest)
where
rest = split' a $ drop (length a) b
Isn't this much nicer to read? Unfortunately, this still doesn't work. rest already has split' a called on it, so you don't need to call split' a on it again in the body of your function:
split' :: String -> String -> [String]
split' a#(d:ds) b#(c:cs)
| a `isPrefixOf'` b = "":rest
| otherwise = (c:head rest):tail rest
where
rest = split' a $ drop (length a) b
Now, this compiles, but it still doesn't work:
λ> split' ", " "1, 2, 3"
["1 ","3*** Exception: Non-exhaustive patterns in function split'
This would be indicative of the fact that we have to add our base cases:
split' :: String -> String -> [String]
-- splitting nothing is nothing
split _ [] = []
-- splitting on empty string just returns array of individual chars
split [] x = map (:[]) x
split' a#(d:ds) b#(c:cs)
| a `isPrefixOf'` b = "":rest
| otherwise = (c:head rest):tail rest
where
rest = split' a $ drop (length a) b
Now, this compiles, but still has non-exhaustive patterns:
λ> split' ", " "1, 2, 3"
["1 ","3*** Exception: Non-exhaustive patterns in function split'
This time, it's because rest could be an empty list. So, we should check for that:
split' :: String -> String -> [String]
split _ [] = []
split [] x = map (:[]) x
split' a#(d:ds) b#(c:cs)
| a `isPrefixOf'` b = "":rest
| otherwise = if null rest
-- if rest is empty we default to just the one character
then [[c]]
else (c:head rest):tail rest
where
rest = split' a $ drop (length a) b
This still doesn't work, since we're removing the length of the delimiter every time, but we really only want to do that if we find a match. If we don't find a match, we should only drop one character.
The final working code is:
split' :: String -> String -> [String]
split' _ [] = []
split' [] x = map (:[]) x
split' a#(d:ds) b#(c:cs)
| a `isPrefixOf'` b = "":(split' a $ drop (length a) b)
| otherwise = if null rest
then [[c]]
else (c:head rest):tail rest
where
rest = split' a $ tail b
As a side note, your code can be cleaned up by using stripPrefix in Data.List instead of isPrefixOf', which allows you to save a drop and avoid iterating over the list twice:
import Data.List
split' :: String -> String -> [String]
split' _ [] = []
split' [] x = map (:[]) x
split' a#(d:ds) b#(c:cs)
| Just suffix <- a `stripPrefix` b = "":split' a suffix
| otherwise = if null rest
then [[c]]
else (c:head rest):tail rest
where
rest = split' a $ tail b
It's also pretty easy to implement yourself:
stripPrefix :: Eq a => [a] -> [a] -> Maybe [a]
stripPrefix [] ys = Just ys
stripPrefix (x:xs) (y:ys)
| x == y = stripPrefix xs ys
stripPrefix _ _ = Nothing
Here's the generic version:
import Data.List
split' :: (Eq a) => [a] -> [a] -> [[a]]
split' _ [] = []
split' [] x = map (:[]) x
split' a#(d:ds) b#(c:cs)
| Just suffix <- a `stripPrefix` b = []:split' a suffix
| otherwise = if null rest
then [[c]]
else (c:head rest):tail rest
where
rest = split' a $ tail b

Couldn't match expected type `Int' with actual type `a'

import Data.List
data Tree a = Leaf a | Node (Tree a) a (Tree a) deriving Show
toTree :: Ord a => [a] -> Tree a
toTree xs = Node (balancedTree (take n xs')) (xs'!!n) (balancedTree (drop n xs'))
where
xs' = sort xs
n = middle xs
middle :: Num a => [a] -> a
middle xs = fromIntegral ((length xs `div` 2) + 1)
balancedTree :: Ord a => [a] -> Tree a
balancedTree (x:[]) = Leaf x
balancedTree xs = Node (balancedTree (take n xs')) (xs'!!n) (balancedTree (drop n xs'))
where
xs' = sort xs
n = middle xs
This is my code for converting from a list to a binary tree. I know there are many mistakes but I just want to get the types errors sorted before I start debugging. I get the following errors in both the "toTree" method and the "balancedTree" method as they are both really the same and will be condensed into one when the errors are sorted out.
ex7.hs:6:38: error:
* Couldn't match expected type `Int' with actual type `a'
`a' is a rigid type variable bound by
the type signature for:
toTree :: forall a. Ord a => [a] -> Tree a
at ex7.hs:5:1-32
* In the first argument of `take', namely `n'
In the first argument of `balancedTree', namely `(take n xs')'
In the first argument of `Node', namely
`(balancedTree (take n xs'))'
* Relevant bindings include
xs' :: [a] (bound at ex7.hs:8:9)
n :: a (bound at ex7.hs:9:9)
xs :: [a] (bound at ex7.hs:6:8)
toTree :: [a] -> Tree a (bound at ex7.hs:6:1)
|
6 | toTree xs = Node (balancedTree (take n xs')) (xs'!!n) (balancedTree (drop n xs'))
| ^
I have tried for hours to fix it by searching stackOverflow but I can't figure it out. The type declaration of "toTree" must stay the same. Also the definition of Tree should stay the same.
My understanding is that "take" required an "Int" and I am giving it an "a". I do not know how I can fix this.
The problem is that middle returns an a, not an Int. Indeed:
middle :: Num a => [a] -> a
middle xs = fromIntegral ((length xs `div` 2) + 1)
But in your balancedTree, you use it as if it is an index, and take n, drop n, and !! n require n to be an Int, indeed:
balancedTree :: Ord a => [a] -> Tree a
balancedTree (x:[]) = Leaf x
balancedTree xs = Node (balancedTree (take n xs')) (xs'!!n) (balancedTree (drop n xs'))
where
xs' = sort xs
n = middle xs
The type signature does not make much sense either. You can calculate the length over any list, not only from lists that consist out of numbers. You thus should construct a function that returns the index in the middle of the list and use that. For example:
middle :: [a] -> Int
middle = (length xs `div` 2) + 1
That being said, using length, etc. is usually not a good idea in Haskell. length requires O(n) time, and furthermore for infinite lists, it will get stuck in an infinite loop. Often if you use functions like length, there is a more elegant solution.
Instead of using a "top-down" approach, it might be better to look at a "bottom-up" approach, where you iterate over the items, and on the fly construct Leafs, and group these together in Nodes until you reach the top.

Haskell component-by-component addition

I am trying do to the component-by-component addition of a list of tuples with the use of higher functions. The result should be the (sum of the first component, sum on the second component).
sumPointwise :: Num a => [(a,a)] -> (a,a)
sumPointwise tl = (sumPw1, sumPw2) -- 42:1
where sumPw1 = foldr (\ x y -> (fst x) + (fst y)) 0 tl
sumPw2 = foldr (\ x y -> (snd x) + (snd y)) 0 tl
But I'm getting the following error:
Couldn't match type `a' with `(a, b0)'
`a' is a rigid type variable bound by
the type signature for sumPointwise :: Num a => [(a, a)] -> (a, a)
at .hs:42:1
In the first argument of `fst', namely `y'
In the second argument of `(+)', namely `(fst y)'
In the expression: (fst x) + (fst y)
It seems like the lambda function is wrong. But I don't get it.
Thanks for your help!
The second argument of foldr is aggregate value: foldr :: (a -> b -> b) -> b -> [a] -> b. So, your expressions should look like
sumPw1 = foldr (\ x s -> (fst x) + s) 0 tl
More succinct way of solving your task is
sumPointwise tl = let (xs, ys) = unzip tl in (sum xs, sum ys)

Concatenating lists in ternary trees

I'm making a function that concatenates ternary trees of lists, using an accumulator.
19 data Ttree t = Nil | Node3 t (Ttree t) (Ttree t) (Ttree t)
20
21 acc :: Ttree [a] -> [a]
22 acc tree = acc' tree []
23
24 acc' :: Ttree [a] -> [a] -> [a]
25 acc' Nil rest = rest
26 acc' (Node3 xs l m r) rest =
27 xs $ acc' l $ acc' m $ acc' r rest
I get this error, using ghc. But I don't see how the expected type of xs is a -> b:
e6.hs:26:4:
Couldn't match expected type `a -> b' against inferred type `[a1]'
In the first argument of `($)', namely `xs'
The left-hand-side of ($) must be a function (i.e. of type a -> b), which xs clearly not. Remember the definition of ($) is
f $ x = f x
it is not a substitution of parenthesis in general. Probably you want
acc' (Node3 xs l m r) rest = xs ++ (acc' l . acc' m . acc' r) rest
instead.
(Note that this is not tail recursive.)
A small addition to Kenny's answer:
Prelude> :t ($)
($) :: (a -> b) -> a -> b

Resources