Have the following in ghci:
:m + Control.Monad.Error
let f x = Right x
Left 1.0 >> Right 1 >>= f
gives
Left 1.0
As I understand >> operator discards monadic result of the first argument,
but I see that here it is preserved. Could you please explain?
http://hackage.haskell.org/package/base-4.10.0.0/docs/src/Data.Either.html#Either
strangely, that link doesn't show how Either is implementing methods of Monad typeclass.
As I understand[, the] >> operator discards monadic result of the first argument,
No, it does not. It more or less sees Left like a Maybe monad sees Nothing (the main difference is that Left also carries a value). Therefore it is sometimes used as an "advanced Maybe" that can for instance carry error messages.
(>>) :: Monad m => m a -> m b -> m b is a function such that f >> g is equivalent to f >>= \_ -> g and f >>= const g. This is the default implementation in the Monad typeclass.
It depends thus on how (>>=) :: Monad m => m a -> (a -> m b) -> m b is implemented.
Now for an Either it is implemented as:
instance Monad (Either e) where
Left l >>= _ = Left l
Right r >>= k = k r
So that means in case of a Left l on the left hand side, then the right hand side is ignored, in case the left hand side is a Right r, then k is applied to the value the Right constructor is wrapping.
So we can replace your query with (added brackets for clarity):
Left 1.0 >> Right 1 >>= f
= (>>) (Left 1.0) (Right 1 >>= f)
-> Left 1.0
Semantically you can see an Either as a "more advanced" version of Maybe where Left takes the place of the Nothing. So from the moment someting is Left x, then it stays Left x. Regardless how we bind it.
Notice the definition contradicts your belief about discarding the left value of a sequence operator:
instance Monad (Either e) where
Left l >>= _ = Left l
Right r >>= k = k r
In fact, in the case of Left the Right value is discarded.
See the source which can be found by clicking on the Monad instance under the Either declaration in the haddocks.
The "result" which is being discarded refers only to the a values contained in (not always literally) an m a value, not the rest of it. In case of Either it means that the value of a Right will be ignored, but not whether it's Left or Right, or the value of a Left.
If you combine the definition of >>= for Either and the default definition of >>, you'll see that >> here is effectively
Left l >> x = Left l >>= \_ -> x = Left l
Right r >> x = Right r >>= \_ -> x = x
and the result in the second clause indeed doesn't depend on r.
Related
I'm trying to understand Applicative and Either's Left. Here is the source:
instance Applicative (Either e) where
pure = Right
Left e <*> _ = Left e
Right f <*> r = fmap f r
I'm unable to understand the Left e <*> _ = Left e part. It makes no sense because this:
Left (+3) <*> Right 5
Would return Left (+3), while this:
Right (+1) <*> Left 3
would return Left 3. The problem is inconsistency. Why would the do this? I apologize if my question isn't clean enough. Thanks!
TL;DR, It's an intentional design decision.
You should think of Right as the "default" state, and Left as the "fallback" state. I do want to make a small correction to your statements above. Left (+3) <*> Right 5 does not produce (+3) as you say, but rather Left (+3). That's an important distinction. The second correction is that Right (+1) <*> Left 3 procues not Left 4, but Left 3. Again, this is important to understand what's going on.
The reason why the <*> operator cannot be symmetric over Either is because the Left and Right constructors don't take the same type. Let's look at the type of <*> specialized to the Either functor:
(<*>) :: Either a (b -> c) -> Either a b -> Either a c
Notice how only the Right side of the first argument is required to be a function. This is so that you can use (<*>) to chain together arguments like this:
Right (+) <$> Right 3 <*> Right 2
> Right 5
But if the first argument were Left 3:
Right (+) <$> Left 3 <*> Right 2
> (Right (+) <$> Left 3) <*> Right 2
> Left 3 <*> Right 2
> Left 3
It also means that you can use (<*>) in general when Left and Right don't have the same type. If Left (+3) <*> Right 5 should produce Left 8, then what should Left (++ "world") <*> Right 5 produce, given that they can both be coerced to the same type, namely Num a => Either (String -> String) a? It's impossible to come up with a satisfactory answer that treats Left and Right equally when they aren't the same type, and a version of Either that was restricted to carrying one type would have severely hampered utility.
This also allows you to treat Left values as exceptional in some way. If at any stage, you end up with a Left value, Haskell will stop performing calculations and just cascade the Left value all the way up. This also happens to match up well with the way a lot of people think about programming. You could imagine creating alternate sets of computations for Left and Right values, but in many cases, you'd just end up filling the Left computations with id anyways, so this isn't too big a limitation in practice. If you want to execute one of a pair of branching computations, you should use regular branching syntax, such as guards, patterns, or case and if statements and then wrap the values up in Either at the end.
If you’re wondering how Right … <*> Left … can still return a Left, it’s because of the fmap call in this definition:
instance Applicative (Either e) where
pure = Right
Left e <*> _ = Left e
Right f <*> r = fmap f r
If we expand the definition of fmap for Either, then the definition of <*> looks like this:
Left e <*> _ = Left e
Right f <*> r = case r of
Left e -> Left e
Right x -> Right (f x)
Or, written more symmetrically with all the cases spelled out explicitly:
Left e1 <*> Left _e2 = Left e1 -- 1
Left e <*> Right _x = Left e -- 2
Right _f <*> Left e = Left e -- 3
Right f <*> Right x = Right (f x) -- 4
I’ve marked with an underscore _ the values that are discarded.
Notice that the only case that returns Right is when both inputs are Right. In fact, that’s the only time it’s possible to return Right.
In case (4) we only have a Right (f :: a -> b) and a Right (x :: a); we don’t have an e, so we can’t return a Left, and the only way we have to obtain a b is by applying f to x.
In cases (1), (2), and (3), we must return a Left, because at least one of the inputs is Left, so we are missing the a -> b or the a that we would need to produce a b.
When both inputs are Left in case (1), Either is biased toward the first argument.
There is a type similar to Either called Validation which combines its “failure” cases, instead of choosing one or the other, but it’s more constrained: it’s only an Applicative, while Either is both an Applicative and a Monad.
Consider this equivalent definition of the instance:
instance Applicative (Either e) where
pure = Right
lhs <*> rhs = case lhs of
Right f -> fmap f rhs
otherwise -> lhs
If lhs isn't a Right, it must be a Left, and so we return it as-is. We don't actually have to match against the wrapped value at all. If it is a Right, we defer to the Functor instance to find out what gets returned.
instance Functor (Either a) where
fmap f (Right x) = Right (f x)
fmap _ l = l
Again, I've given a definition that emphasizes that the content of the Left value doesn't matter. If the second argument isn't a Right, we don't have to explicitly match on it; it must be a Left, and we can just return it as-is.
If Either fmap is
(a -> b) -> p a a -> p a b
which stops mapping once a Left is returned.
What's name or type signature for a function which doesn't stop until it gets a Right result.
I suspect a bifunctor, but I really need it spelled out - don't quite get the subtlety of the logic of these things yet.
Perhaps some sort of fold fits also...
Data.Bifunctor.first :: (a -> b) -> Either a c -> Either b c
In ghci:
Data.Bifunctor> first (+1) (Left 0)
Left 1
Data.Bifunctor> first (+1) (Right 0)
Right 0
Is it possible to create a function of the following signature?
ExceptT A (ExceptT B m) () -> ExceptT B m A
My idea was something along these lines, for x being the parameter of the above mentioned function (and I suck with monads, so its most probably wrong).
runExceptT x :: ExceptT B m (Either A ())
But then I am stuck at getting anything like Either A () -> A which would inherently have to account for Right and thus either fail or return some constant of A (which I dont have).
However, I know that the original value of x is exactly one of the left values because otherwise the definition loops indefinitely.
The OP clarified in a comment:
I have some value [x] that is of type ExceptT B m (). That value may be either left or right. However, then I do forever x and then it becomes left at some point (m is StateT) or it never terminates.
The problem is that you prematurely fixed the type of the result to (). When you run an action forever, you get any result type you want. In particular, you can fix the left and right sides to the same type, and suddenly everything just works. That is, you can write something like
either return return =<< runExceptT (forever x)
and you'll end up with an action that returns the exception if one occurs.
Short answer: that's not possible.
Long answer: ExceptT e m a contains a m (Either e a), so ExceptT A (ExceptT B m) () contains a ExceptT B m (Either A ()), which in turn contain a m (Either B (Either A ())). The question is: how can we get a m (Either B A)from there?
Let's forget about the m, because it doesn't matter. We want a function with that does:
awesomeFunction :: Either B (Either A ()) -> Either B A
A value of type Either B (Either A ()) can be Left b, Right (Left a) or Right (Right ()), meaning you can have a A, a B or nothing.
A value of type Either B A can be Left b or Right a. Let's try to implement awesomeFunction.
awesomeFunction (Left b) = Left b
awesomeFunction (Right (Left a)) = Right a
awesomeFunction (Right (Right ()) = ???
In the situation were we have nothing (a Right (Right ()), we can't create an A from thin air, so it's impossible to create this function.
Since the following do block:
do
x <- foo
y <- bar
return x + y
is desugared to the following form:
foo >>= (\x -> bar >>= (\y -> return x + y))
aren't \x -> ... and y -> ... actually continuations here?
I was wondering if there is a way to capture the continuations in the definition of bind, but I can't get the types right. I.e:
data Pause a = Pause a | Stop
instance Monad Pause where
return x = Stop
m >>= k = Pause k -- this doesn't work of course
Now I tried muddling around with the types:
data Pause a = Pause a (a -> Pause ???) | Stop
------- k ------
But this doesn't work either. Is there no way to capture these implicit continuations?
Btw, I know about the Cont monad, I'm just experimenting and trying out stuff.
OK I'm not really sure, but let me put a few thoughts. I'm not quite sure what it
ought to mean to capture the continuation. You could, for example, capture the whole
do block in a structure:
{-# LANGUAGE ExistentialQuantification #-}
import Control.Monad
data MonadExp b = Return b | forall a. Bind (MonadExp a) (a -> MonadExp b)
instance Monad MonadExp where
return x = Return x
f >>= g = Bind f g
For example:
block :: MonadExp Int
block = do
x <- return 1
y <- return 2
return $ x + y
instance Show (MonadExp a) where
show (Return _) = "Return _"
show (Bind _ _) = "Bind _ _"
print block
>> Bind _ _
And then evaluate the whole thing:
finish :: MonadExp a -> a
finish (Return x) = x
finish (Bind f g) = finish $ g (finish f)
print $ finish block
>> 3
Or step through it and see the parts
step :: MonadExp a -> MonadExp a
step (Return _) = error "At the end"
step (Bind f g) = g $ finish f
print $ step block
>> Bind _ _
print $ step $ step block
>> Return _
Well, now that I think about it more, that's probably not what you're asking. But
maybe it'll help you think.
Well, I don't know if your lambdas are continuations in the strictest sense of the term, but they also look similar to this concept in my eye.
But note that if they are continuations, then the desugared monadic code is already written in continuation passing style (CPS). The usual notion of a control operator that "captures" a continuation is based on direct-style programs; the "captured" continuation is only implicit in the direct-style program, but the CPS transformation makes it explicit.
Since the desugared monadic code is already in CPS or something like it, well, maybe a way to frame your question is whether monadic code can express some of the control flow tricks that CPS code can. Typically, those tricks boil down to the idea that while under the CPS regime it is conventional for a function to finish by invoking its continuation, a function can choose to replace its continuation with another of its choosing. This replacement continuation can be constructed with a reference to the original continuation, so that it can in turn "restore" that original one if it chooses. So for example, coroutines are implemented as a mutual "replace/restore" cycle.
And looked at in this light, I think your answer is mostly no; CPS requires that in foo >>= bar, foo must be able to choose whether bar will be invoked at all, and foo must be abble to supply a substitute for bar, but (>>=) by itself does not offer a mechanism for foo to do this, and more importantly, (>>=) is in control of the execution flow, not foo. Some specific monads implement parts or all of it (for example, the Maybe monad allows foo to forego execution of bar by producing a Nothing result), but others don't.
Closest I could get is to forego (>>=) and use this instead:
-- | Execute action #foo# with its "continuation" #bar#.
callCC :: Monad m => ((a -> m b) -> m b) -> (a -> m b) -> m b
foo `callCC` bar = foo bar
Here foo can choose whether bar will be used at all. But notice that this callCC is really just ($)!
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:
case getValue of
Right x -> Right $ negate x
e -> e
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:
negate `fmap` getValue
Or, with import Control.Applicative, you can use <$> as a synonym for fmap (negate <$> getValue). The fmap function has type fmap :: Functor f => (a -> b) -> f a -> f b. For any functor1, fmap converts a function on ordinary values to a function within the functor. For instance, lists are a functor, and for lists, fmap = map. Here, Either e represents a functor which is either an exception Left e or a value Right a; applying a function to a Left does nothing, but applying a function to a Right applies it within the Right. In other words,
instance Functor (Either e) where
fmap _ (Left l) = Left l
fmap f (Right r) = Right $ f r
Thus the case version is the direct answer to your question, but your particular example is more nicely approximated by fmap.
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 fmap for specific types is often readily usable (especially, in my opinion, when written <$>).
Answer to the title of this question:
I don't see big difference between "... where" and "let ... in ...". Both allows you do declare several cases of function argument bindings:
f val = let negR (Right x) = Right (negate x)
negR y = y
in negR val
or
let { negR (Right x) = Right (negate x); negR y = y; } in negR val