The purpose for this particular portion of code is to make the size
function more efficient than simply counting all the elements in elems
. I've settled on summing the two types that make up the list, but I can't seem to create the signature of the size function.
instance (Finite a, Finite b) => Finite (Either a b) where
elems = combineLists [Left x | x <- elems] [Right x | x <-elems]
size ??? = (size a) + (size b)
From Prelude, we know that Either a b = Left a | Right b
.
The first thing I tried was to match Either
, but of course it is a type, so that doesn't work. Next, I tried ((Left a) | (Right b))
, but no go on that either. Nothing else seems to match the type Either a b
.
I was able to get size (Left a)
to compile, but since it's missing the b
component, I receive the error:
Ambiguous type variable `b' in the constraint:
`Finite b' arising from a use of `size' at <interactive>:1:0-12
which of course makes sense in the context, but I really have no clue how to match Either a b
.
Anybody have any thoughts?
We use pattern matching in Haskell to simplify our codes by identifying specific types of expression. We can also use if-else as an alternative to pattern matching. Pattern matching can also be seen as a kind of dynamic polymorphism where, based on the parameter list, different methods can be executed.
In Haskell either is used to represent the possibility of two values. Either is used to represent two values that can be correct or error. It has two constructors also which are named Left and Right. These constructors also represent and show some purpose either in Haskell.
It's merely an infix synonym for fmap , so you can write e.g. Prelude> (*2) <$> [1.. 3] [2,4,6] Prelude> show <$> Just 11 Just "11" Like most infix functions, it is not built-in syntax, just a function definition. But functors are such a fundamental tool that <$> is found pretty much everywhere.
It represents "computations that could fail to return a value". Just like with the fmap example, this lets you do a whole bunch of computations without having to explicitly check for errors after each step.
Something of type Either a b
is either a Left a
or a Right b
, so you have two cases that can be handled separately:
size (Left x) = size x
size (Right x) = size x
The error about the ambiguous type variable is a separate issue.
If you just type something like size (Left 1)
into the interpreter, the system can't deduce what the "right" type of that Left 1
value would be. It could be Either Int anything
and as long as it is not known what type that anything
is, it cannot be checked if it is in class Finite
(which is required by size
).
You can avoid that problem by specifying an explicit type signature:
size (Left 1 :: Either Int String)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With