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

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.

Related

Haskell Function

I need to create a function that takes string and decoding rules. It is supposed to change characters in string until there is nothing possible to change according to decoding rules.
Each time I get string and decoding rules (first is what change, second is to what).
I'm quite lost, I tried to create all possible combinations and then generate list based on rules. Here's my try.
rules = [('E',"GZ"),('F',"HK"),('C',"EF"),('J',"CC")]
string = "JCEJ"
combinations = [(x,y,z) | x <- [ch | ch <- string], y <- [x | (x,y) <- rules], z <- [y | (x,y) <- rules]]
generate = [z | (x,y,z) <- combinations, if x == y then z else x]
Error message:
decoder.hs:8:57: error:
• Couldn't match expected type ‘Bool’ with actual type ‘[Char]’
• In the expression: z
In the expression: if x == y then z else x
In a stmt of a list comprehension: if x == y then z else x
|
8 | generate = [z | (x,y,z) <- combinations, if x == y then z else x]
| ^
decoder.hs:8:64: error:
• Couldn't match expected type ‘Bool’ with actual type ‘Char’
• In the expression: x
In the expression: if x == y then z else x
In a stmt of a list comprehension: if x == y then z else x
|
8 | generate = [z | (x,y,z) <- combinations, if x == y then z else x]
| ^
Disclaimer: none of this is as pretty as it could be.
You have a lookup table with rules. Haskell has a handy lookup function:
ghci> :t lookup
lookup :: Eq a => a -> [(a, b)] -> Maybe b
We can fold a lookup over the string:
ghci> foldr (\x i -> case lookup x rules of {Just s -> s ++ i; _ -> (x:i)}) "" "EF"
"GZHK"
Let's call this singlePassDecode:
singlePassDecode :: Foldable t => t Char -> [(Char, [Char])] -> [Char]
singlePassDecode s rules = foldr update "" s
where
update ch acc =
case lookup ch rules of
Just s' -> s' ++ acc
Nothing -> ch : ""
But a single pass doesn't necessarily get the job done. We need to recursively call this until there are no transformations left to perform. This means we need to know if any of the characters in the input string are in the lookup table.
The ... is left to fill in with the correct recursive call to avoid presenting a complete answer.
decode :: [Char] -> [(Char, [Char])] -> [Char]
decode s rules
| any (\ch -> elem ch (map fst rules)) s = ...
| otherwise = s
The first condition might also be expressed as follows.
any (flip elem $ map fst rules) s
A String is a list of Chars, so the [ch | ch <- string] is not necessary.
You here defined some inner list comprehensions with x, but that x is a more locally scoped variable, not the x as the x in x <- [ ch | ch <- str].
You can make a filter condition to filter, so:
generate = concat [ y | x <- string, (x', y) <- rules, … ]
Here the … is a part that you will need to fill in. It will need to compare x with x'.
Your list of rules describes a mapping from one Char to either two Chars (if there is a match) or one Char (the original input, if there is no match). We can handle both of those cases by always returning a [Char], and we can generalize to any a rather than being specific to Char:
import Data.Maybe (fromMaybe)
transform :: Eq a => [(a, [a])] -> a -> [a]
transform rules x = fromMaybe [x] (lookup x rules)
Since this mapping depends on no other context, concatMap (also spelled (>>=)) is a great tool for applying it across a list of inputs and concatenating the results.
transformAll :: Eq a => [(a, [a])] -> [a] -> [a]
transformAll rules = concatMap (transform rules)
-- or, transformAll = concatMap . transform
It will also be useful to have a function that applies a function repeatedly until it results in no change:
fixPoint :: Eq a => (a -> a) -> a -> a
fixPoint f x | x == x' = x
| otherwise = fixPoint f x'
where x' = f x
Then all that's left is to combine our tools:
transformStringRepeatedly :: Eq a => [(a, [a])] -> [a] -> [a]
transformStringRepeatedly rules = fixPoint (transformAll rules)
-- or, transformStringRepeatedly = fixPoint . transformAll
main = print (transformStringRepeatedly [('E',"GZ"),('F',"HK"),('C',"EF"),('J',"CC")] "JCEJ")
We can see that it produces the answer you expected:
$ runghc tmp.hs
"GZHKGZHKGZHKGZGZHKGZHK"

Instance Eq is not working in Haskell

So I was given the following data type and I had to write a code that checks if an element is in the list (I think I did this one right).
After this I had to declare instance Eq where it would be True if both of my amount lists would be equal. I was supposed to use the element code I wrote earlier.
Could someone tell me what I am doing wrong?
data Amount a = Amount [a]
element [] _ = False
element (x:xs) y = ( x==y) || element xs y
instance Eq (Amount a) where
Amount xs == Amount ys = element xs ys && element ys xs
This is the error message I am receiving
• Couldn't match expected type ‘a’ with actual type ‘[a]’
‘a’ is a rigid type variable bound by
the instance declaration at Probeklausur1.hs:43:10-22
• In the second argument of ‘element’, namely ‘ys’
In the first argument of ‘(&&)’, namely ‘element xs ys’
In the expression: element xs ys && elementS ys xs
• Relevant bindings include
ys :: [a] (bound at Probeklausur1.hs:44:27)
xs :: [a] (bound at Probeklausur1.hs:44:14)
(==) :: Amount a -> Amount a -> Bool
(bound at Probeklausur1.hs:44:17)
|
44 | Amount xs == Amount ys = element xs ys && elementS ys xs | ^^
Probeklausur1.hs:44:49: error:
• Variable not in scope: elementS :: [a] -> [a] -> Bool
• Perhaps you meant ‘element’ (line 40)
|
44 | Amount xs == Amount ys = element xs ys && elementS ys xs | ^^^^^^^^
Let us first analyze the type of element:
element [] _ = False
element (x:xs) y = ( x==y) || element xs y
We see that the first item is a list [a] (based on the [] and (:) data constructors). Furthermore we know that the second item has as type the type of the elements of the list, so a, and since we call x == y, there must be an Eq a constraint. So we derive:
element :: Eq a => [a] -> a -> Bool
A very similar builtin function already exists for this: elem :: Eq a => a -> [a] -> Bool, so it is probably better to use this one instead.
But let us now look at the instance declaration:
instance Eq (Amount a) where
Amount xs == Amount ys = element xs ys && element ys xs
There are two problems here:
we need a to have an Eq type constraint as well, since we need to check if the elements of the list are the same; and
we call element with xs and ys, but both xs and ys have type [a], so this will not work.
We thus first need a mechanism to check that all elements of one list occur in the other list. We can check this with the all :: (a -> Bool) -> [a] -> Bool function:
allElem :: Eq a => [a] -> [a] -> Bool
allElem xs = all (flip elem xs)
So now we can write it like:
instance Eq a => Eq (Amount a) where
Amount xs == Amount ys = allElem xs ys && allElem ys xs
Note that the above might still not be exactly what you want for two reasons:
the order of the two lists is not checked, I assume that this is intentional;
if an element occurs multiple times in the first list, then it does not have to occur that many times in the second list, as long as it occurs at least once we are fine. The length of the two lists can thus be different, and still the two Amounts are considered equal.

How can I use generic type annotations to describe a recursive data type?

Here's the function:
comboGraph :: [a] -> Int -> [b]
comboGraph _ 0 = []
comboGraph [] _ = []
comboGraph (x:xs) n =
(buildEdges x xs) : comboGraph xs n
where buildEdges h t = (h, comboGraph t (n-1))
Ths function takes in a list of type a, a number, and returns a list of type b. As you can see, though, type b is actually a recursive type -- it will be something along the lines of [(a, [(a, b1)])]. When I try to compile, I get this error:
• Couldn't match type ‘b’ with ‘(a, [b0])’
‘b’ is a rigid type variable bound by
the type signature for:
comboGraph :: forall a b. [a] -> Int -> [(a, [b])]
at xxx.hs:15:15
Expected type: [(a, [b])]
Actual type: [(a, [(a, [b0])])]
• In the expression: (buildEdges x xs) : comboGraph xs n
In an equation for ‘comboGraph’:
comboGraph (x : xs) n
= (buildEdges x xs) : comboGraph xs n
where
buildEdges h t = (h, comboGraph t (n - 1))
How do I properly annotate this function?
To make the issue a bit more evident, let's substitute the definition of buildEdges in the final case of your definition:
comboGraph (x:xs) n =
(x, comboGraph xs (n-1)) : comboGraph xs n
The result of comboGraph is supposed to be a list, but one whose elements are pairs that also have a comboGraph result (i.e. a list of the same type) within. As the type error you got says, that doesn't work -- it's as if you wanted a list with two tails. The fix is switching to a different data structure that reflects what you are trying to do:
-- Feel free to substitute better names.
data Combo a = Empty | Node a (Combo a) (Combo a)
deriving (Eq, Ord, Show)
Empty covers the base cases which used to result in an empty list, while Node has one appropriately-typed field for each of the things you want to combine in the recursive case. comboGraph then becomes:
comboGraph :: [a] -> Int -> Combo a
comboGraph _ 0 = Empty
comboGraph [] _ = Empty
comboGraph (x:xs) n = Node x (comboGraph xs (n-1)) (comboGraph xs n)
(Note that Combo is actually a binary tree with values on the nodes.)
I like the other answer, and I think you should use it. But it makes some reasoning leaps that require some intuition, and it can be hard to get this intuition without doing things the mechanical way a few times. So in this answer, I will show how to start with a failing definition like the one you have, "turn a crank", and mechanically get a solution that does work. The technique below can be applied to any infinite type error.
You have the following clause (paraphrased slightly):
comboGraph (x:xs) n =
(x, comboGraph xs (n-1)) : {- ... -}
Just doing some straightforward type inference reasoning, we can see that comboGraph takes a list of some type (from the fact that it pattern matches on x:xs) and a number (from the fact that it subtracts one). Let's pick a concrete (monomorphic! but not yet known) type a for the list elements and see what we can infer about what it returns.
Well, it clearly returns a list with tuples inside. And the first part of the tuple is just an a. What about the second part? The second part of the tuple is... whatever type comboGraph returns. So comboGraph returns a type t satisfying the equation:
t = [(a, t)]
The only solution to this equation is [(a, [(a, [(a, [(a, ...)])])])]. Such infinite types don't exist raw in Haskell. But there is a standard trick to get quite close: use (type-level) recursion by introducing a newtype. We're solving for t, but Haskell types have to start with an upper-case letter, so we'll name our solution to this equation T.
newtype T a = T [(a, T a)] deriving Show
Now we don't quite have T a ~ [(a, T a)], but we do have an isomorphism: namely, \(T xs) -> xs :: T a -> [(a, T a)] and T :: [(a, T a)] -> T a are inverses. So now we can write your comboGraph definition by exploiting this isomorphism. Let's name the other half of the isomorphism:
unT :: T a -> [(a, T a)]
unT (T xs) = xs
So:
comboGraph (x:xs) n =
T ((x, comboGraph xs (n-1)) : unT (comboGraph xs n))
The base cases have to get wrapped in T, as well, of course:
comboGraph _ 0 = T []
comboGraph [] _ = T []
Try it in ghci:
> comboGraph "abc" 3
T [('a',T [('b',T [('c',T [])]),('c',T [])]),('b',T [('c',T [])]),('c',T [])]

Haskell filter function with multiple parameters

I'm trying to learn Haskell and wondered how to filter a given list, with a function that takes multiple parameters, passing each element of the list with other unchanging elements to the function, to create a new list.
I understand that I can do this to use a bool function to filter the list:
newList = filter theFunction aList
but what happens when the theFunction takes other parameters like this:
theFunction -> elementOfAList -> Int -> Bool
how then could I filter each element of the list, whilst parsing in another element to the function? Any help would be greatly appreciated :)
Edit -> To provide some more information, if I wanted to have a list of integers from [1..10], that get filtered through a function that takes two integers and returns true if the first one is smaller, how could I do that?
In that case you use a partially applied predicate function, like this
-- theFunction :: elementOfAList -> Int -> Bool -- "::" means, "is of type"
newList = filter (flip theFunction i) aList
because
flip theFunction i x = theFunction x i
by the definition of flip, so flip theFunction has the type Int -> elementOfAList -> Bool:
flip :: (a -> b -> c ) -> b -> a -> c
theFunction :: a -> Int -> Bool
flip theFunction :: Int -> a -> Bool
flip theFunction (i :: Int) :: a -> Bool
where i is some Int value defined elsewhere. a is a type variable, i.e. it can be any type, like the type of a list's elements (i.e. for a list aList :: [a] each element has the same type, a).
For example, with theFunction x i = x < i you could call filter (flip theFunction 5) aList, keeping in the resulting list all the elements of aList that are smaller than 5. Normally this would just be written as filter (< 5) aList, with operator sections (of which (< 5) is one example, absolutely equivalent to the flip theFunction 5).
The above filtering will use the same Int value i in calling theFunction for every element x of a list aList. If you wanted to recalculate that Int, it is done with another pattern (i.e., higher-order function),
mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
Suppose you wanted to keep in a list of ints all the elements as they are being found by theFunction. Then you could do it like
theFunction :: elementOfAList -> Int -> Bool
foo :: Int -> [Int] -> [Int]
foo i xs = concat (snd (mapAccumL g i xs)) -- normally written as
-- concat $ snd $ mapAccumL g i xs -- or
-- concat . snd $ mapAccumL g i xs -- or even
-- concat . snd . mapAccumL g i $ xs
where
g acc x -- g :: (acc -> x -> (acc, y)) according to mapAccumL's signature
| theFunction x acc = (x, [x]) -- include `x` in output, and update the acc
| otherwise = (acc, []) -- keep the accumulated value, and skip this `x`
Because both x and acc are used in the same role (the first element of the tuple) they both must be of same type.

Guards and where haskell

I have a very basic Haskell function.
It should prepend a tuple to list if not present returning it.
Added tuple needs to be edited before prepending.
I expect a function whose type is this:
Num t => (a, t) -> [(a, t)] -> [(a, t)]
Function is this:
update x lst
| hasElement x lst == True = addElement x lst
| otherwise = lst
where hasElement element list = not (null (filter ((==element).fst) list))
addElement a b = (fst a, (snd a) +1) : b
but I got an error when I try to load the module:
• Occurs check: cannot construct the infinite type: a ~ (a, t)
Expected type: [(a, t)]
Actual type: [((a, t), t)]
• In the second argument of ‘addElement’, namely ‘lst’
In the expression: addElement x lst
In an equation for ‘update’:
update x lst
| hasElement x lst == True = addElement x lst
| otherwise = lst
where
hasElement element list
= not (null (filter ((== element) . fst) list))
addElement a b = (fst a, (snd a) + 1) : b
• Relevant bindings include
lst :: [((a, t), t)] (bound at pip.hs:40:10)
x :: (a, t) (bound at pip.hs:40:8)
update :: (a, t) -> [((a, t), t)] -> [(a, t)]
(bound at pip.hs:40:1)
The addElement return type seems breaks all up since commenting it out makes the module work.
Question is: what's wrong?
Trying function alone seems working as I expect.
Thanks,
FB
The reason for that particular error is that element contains both a key and a value, but by (==element) . fst you try to compare only the key.
The best way to actually get only at the key is to pattern match it right in the function argument. Note that you don't really need the element variable at all, nor the other arguments to the local functions:
update (key,y) lst
| hasElement = addElement -- comparing `==True` is a no-op!
| otherwise = lst
where hasElement = not . null $ filter ((==key).fst) lst
addElement = (key, y+1) : b
I'd question though if this behaviour of addElement is really what you want: you're not updating the existing element with a given key, but adding a new element with the same key?
Also, the combination of not, null and filter is needlessly complicated. You can just use
hasElement = any ((==key).fst) lst
Finally, the signature Num a => ... is actually not strong enough: you're comparing keys with ==. That only works if the keys have an Eq instance. So, this is the correct signature:
(Eq a, Num t) => (a, t) -> [(a, t)] -> [(a, t)]

Resources