I want to make the data type Moneda a instance of the Semigroup, and implement the associative operation as +. I'm having difficulties understanding it properly.
The working solution I found, is the following:
data Moneda a = RON Double | EUR Double deriving (Show)
instance Num a => Num (Moneda a) where
(RON x) + (RON y) = RON (x + y)
(RON x) + (RON y) = RON (x + y)
instance Semigroup (Moneda a) where
(<>) = (+)
I couldn't understand why exactly the below aproach is failing and how it's possible to make it work without making Moneda a Num instance.
data Moneda a = RON a | EUR a deriving (Show)
instance Semigroup (Moneda a) where
(<>) (RON a) (RON b) = (RON a+b) -- fails, please see error below
vs
(<>) (RON a) (RON b) = (RON a) -- works but doesn't help me because I need the a+b sum
-- cannot construct the infinite type: a ~ Moneda a
-- In the second argument of `(+)', namely `b'
The error you're getting is because you try to add a value of type
Moneda ato a value of typeain your implementation of(<>). That is you wrote(RON a+b)which parses as(RON a) + b(because function/constructor application binds stronger than addition). You probably meant to writeRON (a + b)as in:But that won't work either as it requires addition to be defined on the type to which you apply
Moneda. So, for your definition to make sense you will need to constrain the instantiation of the type argumentato types inNum:For example:
Note that this definition of
(<>)is only partial. It does not account for adding values built withRONto values built withEUR:So, you still have to write code that deals with those cases.