# How to derive Eq from Data.Either?

Hello!

Given this implementation:

``````mul :: forall m n. Bind m => Applicative m => Semiring n => m n -> m n -> m n
mul ma mb = do
a <- ma
b <- mb
pure (a * b)
``````

I can make these tests pass:

``````  -- ...
assert \$
Just 12 ==
mul (Just 3) (Just 4)

assert \$
Nothing ==
mul Nothing (Just 4)

assert \$
Nothing ==
mul (Just 3) Nothing
``````

However, introducing Either requires me to implement `Eq`

``````  assert \$
Right 12 ==
mul (Right 3) (Right 4)
``````

I did find a reference for this requirement in the `Data.Either` docs:

``````(Eq a) => Eq1 (Either a)
(Ord a, Ord b) => Ord (Either a b)
The Ord instance allows Either values to be compared with compare, >, >=, < and <= whenever there is an Ord instance for both types the Either can contain.

Any Left value is considered to be less than a Right value.
``````

But I can’t quite understand how I should implement this. My hunch is that I need to tweak the type signature but I’m not sure.

Could you show me how what I’m missing?

1 Like

Hi - the issue is with the tests - those need the instance to be `Eq` and indeed I think the problemis not the code you wrote (this should be `Eq`, including `Right 3`) but that the `Left` type of your `Either` will not be known (and thus infered as some type-variable `a`) and thus the typechecker will complain - you should be able to help out like this: `assert \$ (Right 12 :: Either String Int) == mul (Right 3) (Right 4)` (basically: give the typechecker a hint)

disclaimer: I did not try this out so chances are that I typed some syntax/type error - sorry

Many thanks, that was it! Makes sens…

I have one last question : in this context, do I have to “commit” `Left`’s type? Intuitively, I’d want to do this:

``````assert \$
(Right 12 :: Either a Int) ==
mul (Right 3) (Right 4)
``````

But that’s obviously wrong. I’m just wondering if I could be missing a cool trick here

you don’t have to “commit” to the type but you have to make sure that it is `Eq` - and I think `Show` but I could be wrong here)

So there needs to be a `forall a. Eq a => Show a => Either a Int` and to be honest: I’m not sure if you can plug this in there (I’m not sure if this is allowed syntax) - I think you could do this with a `let` or `where`:

``````assert \$ expected ...
where
expected :: forall a. Eq a => Show a => Either a Int
expected = Right 12
``````

It looked like a cool idea but it didn’t work unfortunately.

I’ll go with being explicit for now, thanks again

ok - I guess Purescript does not fall back to defaults then (the actual code you gonna run needs actual types as the type-class instances are passed via a dictionary - I somehow thought Purescript would use default types - when I think about it it’s probably a rather stupid assumption - sorry)

2 Likes

Yeah, Haskell has a defaulting mechanism that we decided not to implement way back in the mists of time. Although it would have been nice in this case, it can also be confusing as it’s very ad-hoc. It’s even worse when you’re in GHCi, as it adds a bunch of extra defaults than then don’t work in real code.

yes that was what I was thinking about - in the end it’s not really a loss IMHO - defaults + monomorphism-restriction while nice can be a huge “WTF” generator in Haskell