How do you extract a value from a variable of an unknown constructor?
For instance, I would like to negate the value in an Either if was constructed as a Right:
let Right x = getValue
in Right (negate x)
This code successfully binds Right’s value (an Int in this case) to x.
This works, but what if getValue returns a Left instead? Is there a way to determine the type of a variable in a let expression? Or is there a better way to approach this problem?
In general, what you can do is this:
What this does should be clear: it’s just like pattern matching in a function argument, but against a value. To do what you need, you have a default case which catches anything not matched, and then return that.
In your particular case, however, you can do something slightly nicer:
Or, with
import Control.Applicative, you can use<$>as a synonym forfmap(negate <$> getValue). Thefmapfunction has typefmap :: Functor f => (a -> b) -> f a -> f b. For any functor1,fmapconverts a function on ordinary values to a function within the functor. For instance, lists are a functor, and for lists,fmap = map. Here,Either erepresents a functor which is either an exceptionLeft eor a valueRight a; applying a function to aLeftdoes nothing, but applying a function to aRightapplies it within theRight. In other words,Thus the
caseversion is the direct answer to your question, but your particular example is more nicely approximated byfmap.1: To a first approximation, functors are "containers". If you’re not comfortable with the various type classes, I recommed the Typeclassopedia for a comprehensive reference; there are many more tutorials out there, and the best way to get a feel for them is to just play with them. However, the
fmapfor specific types is often readily usable (especially, in my opinion, when written<$>).