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.
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
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
.
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 x
s ( 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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.