I have recieved a exercice to learn about data types in haskell and I can't figure out how to solve this one.
They got me a data like : data CatLista a = Nil | Unit a| Conc (CatLista a) (CatLista a) deriving Eq
and I need to make the data types become: Nil -> [] , Unit x -> [x] , Conc -> same operator as (++)
So if you run Conc (Unit 9)(Conc (Unit 5) (Unit 3)) == Conc (Conc (Unit 9) (Unit 5))(Conc (Unit 3) Nil)
should give true and Conc (Unit 9)(Unit 3) == Conc (Unit 3) (Unit 9)
should give false.
I already tried instancing the show class like this:
instance Show a => Show (CatLista a) where
show a = case a of
Nil -> []
Unit x -> "[" ++ show x ++ "]"
Conc Nil dos -> show dos
Conc uno Nil -> show uno
Conc uno dos -> "[" + show uno ++ "," ++ show dos ++ "]"
I'm quite new to haskell so I may not know some basics, because I can't understand why if I run it (beeing Conc uno dos -> show uno ++ show dos
) with the same command as bellow Conc (Unit 9)(Conc (Unit 5) (Unit 3)) == Conc (Conc (Unit 9) (Unit 5))(Conc (Unit 3) Nil)
it still returns False even tough they both return the same [9][5][3] with my show instance.
EDIT
Thanks to you I made it, it know returns correctly the values like intended with this code:
toLista :: Eq a => CatLista a -> [a]
toLista Nil = []
toLista (Unit x) = [x]
toLista (Conc a b)
| a == Nil = toLista b
| b == Nil = toLista a
| otherwise = (++) (toLista a) (toLista b)
instance (Show a,(Eq a)) => Show (CatLista a) where
show a= show (toLista a)
But still I dont know why if I try the same comparation it still returns False, even tough I get returned the same [9,5,3].
This is probably due to my lack of knowledge in Haskell, sorry about that.
Two values are not equivalent if these produce the same String
when calling show
on these. The (==) :: Eq a => a -> a -> Bool
function is implemented by the Eq
typeclass. You thus need to implement the instance
of Eq
for your CatLista
yourself.
The default implementation for Eq
, if you use deriving Eq
is that two values are the same if they have the same data constructor, and the parameters are elementwise equivalent by calling (==)
on these.
You thus can implement the instance for Eq
yourself with:
data CatLista a = Nil | Unit a| Conc (CatLista a) (CatLista a) -- ← no deriving Eq
instance Eq a => Eq (CatLista a) where
ca == cb = toLista ca == toLista cb