How do I apply a series of monadic actions to the same argument in Haskell? - haskell

In Haskell, is there a way to simplify the following code to remove the repeating of "hello world"? In other words, applying f, g, and h to hello world?
fn = do
a <- f "hello world"
b <- g "hello world"
c <- h "hello world"
return (a, b, c)

If f, g and h have the same type, you can simply loop over them:
[a,b,c] <- forM [f,g,h] ($"hello world")
If they have different types, you can use the fact that functions form a monad, and in particular can be stacked as a monad transformer on top of your current monad:
import Control.Monad.Trans.Reader
fn = (`runReaderT`"hello world") $ do
a <- ReaderT f
b <- ReaderT g
c <- ReaderT h
return (a, b, c)

Related

Haskell: Run two monads, keep the result of the first one

Playing with Haskell and now I try to create a function like
keepValue :: (Monad m) => m a -> (a -> m b) -> m a
with following semantic: it should apply monad value to a function, which return the second monad, and keep the result of the first monad, but the effect of the second one
I have a working function in case of Maybe monad:
keepValueMaybe :: Maybe a -> (a -> Maybe b) -> Maybe a
keepValue ma f = case ma >>= f of
Nothing -> Nothing
Just _ -> ma
So if the first value is Nothing, the function is not run (so no second side-effect), but if the first value is Just, then, the function is run (with side effect). I keep effect of the second computation (e.g., Nothing makes the whole expression Nothing), but the original value.
Now I wonder. Can it work for any monad?
It looks kinda built-in >>, but I couldn't find anything in standard library.
Let's walk through this!
keepValue :: Monad m => m a -> (a -> m b) -> m a
keepValue ma f = _
So what do we want keepValue to do? Well, the first thing we should do is use ma, so we can connect it to f.
keepValue :: Monad m => m a -> (a -> m b) -> m a
keepValue ma f = do
a <- ma
_
Now we have a value va of type a, so we can pass it to f.
keepValue :: Monad m => m a -> (a -> m b) -> m a
keepValue ma f = do
va <- ma
vb <- f va
_
And finally, we want to produce va, so we can just do that:
keepValue :: Monad m => m a -> (a -> m b) -> m a
keepValue ma f = do
va <- ma
vb <- f va
return va
This is how I'd walk through writing the first draft of any monadic function like this. Then, I'd clean it up. First, some small things: since Applicative is a superclass of Monad, I prefer pure to return; we didn't use vb; and I'd drop the v in the names. So for a do-notation based version of this function, I think the best option is
keepValue :: Monad m => m a -> (a -> m b) -> m a
keepValue ma f = do
a <- ma
_ <- f a
pure a
Now, however, we can start to make the implementation better. First, we can replace _ <- f va with an explicit call to (>>):
keepValue :: Monad m => m a -> (a -> m b) -> m a
keepValue ma f = do
a <- ma
f a >> pure a
And now, we can apply a simplification. You may know that we can always replace (>>=) plus pure/return with fmap/(<$>): any of pure . f =<< ma, ma >>= pure . f, or do a <- ma ; pure $ f a (all of which are equivalent) can be replaced by f <$> ma. However, the Functor type class has another, less-well-known method, (<$):
(<$) :: a -> f b -> f a
Replace all locations in the input with the same value. The default definition is fmap . const, but this may be overridden with a more efficient version.
So we have a similar replacement rule for (<$): we can always replace ma >> pure b or do ma ; pure b with b <$ ma. This gives us
keepValue :: Monad m => m a -> (a -> m b) -> m a
keepValue ma f = do
a <- ma
a <$ f a
And I think this is the shortest reasonable version of this function! There aren't any nice point-free tricks to make this cleaner; one indicator of that is the multiple use of a on the second line of the do block.
Incidentally, a terminology note: you're running two monadic actions, or two monadic values; you're not running *"two monads". A monad is something like Maybe – a type constructor which supports (>>=) and return. Don't mix the values up with the types – this sort of terminological distinction helps keep things clearer!
This structure looks a lot like the definition of >>=/>> for Monad Maybe.
case foo of
Nothing -> Nothing
Just _ -> bar
foo >>= \_ -> bar
foo >> bar
so your original expression could be simplified to
ma >>= f >> ma
and this works for other monads.
However, I don't think this is actually what you want, as you can see ma occurring twice. Instead, take the value from the first ma >>= bind, and carry it through to the end of the computation.
keepValue ma f =
ma >>= \a ->
f a >>
return a
or in do-notation
keepValue ma f = do
a <- ma
f a
return a
You could define:
passThrough f = (>>) <$> f <*> pure
and then inplace of
keepValue ma f
write
ma >>= passThrough f
Then to read a line and print it twice (say) would be
getLine >>= passThrough putStrLn >>= putStrLn

How does the Reader monad's "ask" function work?

data T b = E | N b (T b) (T b)
f :: T b -> Reader Int (T Int)
f (N i l r) = ask >>= \x -> local ((-)4) (f l) >>= \l' -> local ((-)1) (f r) >>= \r' -> return (N x l' r')
f E = return E
I have a problem with understanding how this code works. Especially, how does ask know where the environment is (in our case just Int)?
To be more precise: I am an imperative programmer and in such languages it is easy. Methods can be called on any object like: obj.f(), or we have to pass data by argument when we want function use external data.
That's kind of what the Reader monad does; it gives you an ask function, which "magically" pops up a value out of thin air. To actually use this, you need to call runReader, and give it the Int environment. The Reader type then automatically propagates that from the runReader call to each of the ask calls.
Short, hand-wavy answer. The Reader Int (T Int) value is essentially just a wrapped-up function of type Int -> (T Int). In order to run that function, we first need to extract it. We do that with runReader.
data T b = ... deriving (Show)
main = let tree = (N 10 (N 8 E E) E)
g = f tree
h = runReader g
in print $ h 20
(Typically, you would simply write print $ runReader (f tree) 20; I split it up to correspond to the sketchy analogy below.)
ask (defined by the MonadReader typeclass and as implemented by the ReaderT monad transformer used to define the Reader type) essentially retrieves the value of the argument passed to h.
In some sense, the Reader Int (T Int) is an object that contains a function g that calls a function ask. runReader g creates a new function which, when called, defines a function ask that simply returns its argument, then calls g. Now when g calls ask, it gets back the argument originally passed to h.
I recomend reading this first. Ask is defined:
ask :: (Monad m) => ReaderT r m r
ask = ReaderT return
and reader:
newtype ReaderT r m a = ReaderT { runReaderT :: r -> m a }
type Reader r = ReaderT r Identity
so
do
r <- ask
...
is equivalent to
do
r <- ReaderT return
...
So essentially <- just reaches into the identity monad, and grabs what ever value that will eventually be lifted by runReader R = return.
This enables global variables in haskell.

Haskell, parameters of ask

Could you help what parameter is getting by ask ?
We often can see ask >>= f
It means that ask >>= f = (\k -> f (ask k) k)
So ask must be able to get k, function from enviroment.
However, in docs it is written: ask :: m r.
Where am I wrong ?
It's the Reader monad. Ultimately the best answer is just to study its implementation, which in it simplest version (no monad transformers, no classes) can be defined like this:
newtype Reader r a = Reader { runReader :: r -> a }
This is a newtype declaration, so Reader r a is just a "relabeling" (so to speak) of the function type r -> a. ask is defined like this:
ask :: Reader r r
ask = Reader (\r -> r)
Which means that ask is a relabeled identity function—the function that just returns its own argument. We can see this if we use the runReader operation to feed values to it :
ghci> runReader ask 5
5
ghci> runReader ask "Hello world!"
"Hello world!"
That doesn't look very useful, but the magic comes from the fact that Reader has instances for Functor, Applicative and Monad:
instance Functor (Reader r) where
fmap f (Reader g) =
-- A `Reader` that applies `f` to the original `Reader`'s results
Reader (\r -> f (g r))
instance Applicative (Reader r) where
pure a =
-- A `Reader` that ignores its `r` argument and just produces
-- a fixed value.
Reader (\_ -> a)
Reader ff <*> Reader fa =
-- A `Reader` that "combines" two `Reader`s by feeding the same
-- `r` value to both, and then combining their results
Reader (\r -> ff r (fa r))
instance Monad (Reader r) where
return = pure
Reader fa >>= k =
-- A `Reader` that feeds the same `r` both to the original one
-- and to the one computed by the `k` function
Reader (\r -> k (fa r) r)
If you study these, you'll notice that what Reader is about is delaying the point of the program where you apply the wrapper r -> a function to an r. Normally, if you have a function of type r -> a and you want to get a value of type a, you have to feed the function an argument of type r. The Reader class instances allow you instead to supply functions that will be used to operate on the a ahead of time, and then supply the r in the end.
The ReaderT type and the MonadReader class (which has the ask :: MonadReader r m => m r method) are just more advanced versions of this.
A value of type m a where m is a Monad, can be thought of as a "monadic action". So ask doesn't take any parameters, it's just a value that you can bind (>>=) to extract some value from a Reader monad.
Look at the definition of ask for ReaderT in Control.Monad.Trans.Reader:
-- | Fetch the value of the environment.
ask :: (Monad m) => ReaderT r m r
ask = ReaderT return
ReaderT is just a data constructor that contains a value of type r -> m a, so ReaderT return is a value of type ReaderT r m r that contains a function, return (of the monad m).
In other words, ask here is a "monadic action" that extracts the value of stored inside the Reader.
ask >>= f
Which is
(ReaderT return) >>= f
Using definition of >>= for Reader, we get:
ReaderT $ \ r -> do
a <- runReaderT (ReaderT return) r
runReaderT (f a) r
Which reduces to
ReaderT $ \ r -> do
a <- return r
runReaderT (f a) r
Or
ReaderT $ \r -> runReaderT (f r) r
So, it passes the stored value along to decide the next action and also passes the value so the next actions can read it as it was before.
(If this wasn't clear, look for a Reader tutorial maybe)

Converting Monad notation to Arrow notation

I'm trying to understand arrow notation, in particularly how it works with Monads. With Monads I can define the following:
f = (*2)
g = Just 5 >>= (return . f)
and g is Just 10
How do I do the above but using arrow notation?
Changing your Monad thinking to Arrow thinking
The first step to translating into Arrow is to move from thinking about m b on its own to thinking about a -> m b.
With a monad, you'd write
use x = do
.....
....
doThis = do
....
...
thing = doThis >>= use
whereas an arrow always has an input, so you'd have to do
doThis' _ = do
.....
....
and then use (>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c from Control.Monad do have
thing' = doThis' >=> use
>=> removes the asymmetry of >>=, and is what we would call the Kleisli arrow of the Monad.
Using () for input or "What if my first thing really isn't a function though?"
That's OK, it's just the co-problem to if your monad doesn't produce anything (like putStrLn doesn't), whereupon you just get it to return ().
If your thing doesn't need any data, just make it a function that takes () as an argument.
doThis () = do
....
....
that way everthing has the signature a -> m b and you can chain them with >=>.
Arrows have input and output, but no function
Arrows have the signature
Arrow a => a b c
which is perhaps less clear than the infix
Arrow (~>) => b ~> c
but you should still be thinking of it as analagous to b -> m c.
The main difference is that with b -> m c you have your b as an argument to a function and can do what you like with it, like if b == "war" then launchMissiles else return () but with an arrow you can't (unless it's an ArrowApply - see this question for why ArrowApply gives you Monad capabilities) - in general, an arrow just does what it does and doesn't get to switch operation based on the data, a bit like an Applicative does.
Converting Monads to Arrows
The problem with b -> m c is that there you can't partially apply it in an instance declaration to get the -> m bit from the middle, so given that b -> m c is called a Kleisli arrow, Control.Monad defines (>>>) so that after all the wrapping and unwrapping, you get f >>> g = \x -> f x >>= g - but this is equivalent to (>>>) = (>=>). (In fact, (.) is defined for Categories, rather than the forwards composition >>>, but I did say equivalent!)
newtype Kleisli m a b = Kleisli { runKleisli :: a -> m b }
instance Monad m => Category (Kleisli m) where
id = Kleisli return
(Kleisli f) . (Kleisli g) = Kleisli (\b -> g b >>= f) -- composition of Kleisli arrows
instance Monad m => Arrow (Kleisli m) where
arr f = Kleisli (return . f)
first (Kleisli f) = Kleisli (\ ~(b,d) -> f b >>= \c -> return (c,d))
second (Kleisli f) = Kleisli (\ ~(d,b) -> f b >>= \c -> return (d,c))
Your example, at last
(Try to ignore all the Kleisli and runKleisli - they're just wrapping and unwrapping monadic values - when you define your own arrow, they're not necessary.)
If we unwrap what that means for the Maybe, we get the equivalent of composing
f :: a -> Maybe b
g :: b -> Maybe c
f >>> g :: a -> Maybe c
f >>> g = \a -> case f a of -- not compilable code!
Nothing -> Nothing
Just b -> g b
and the Arrow way of applying a (pure) function is with arr :: Arrow (~>) => (b -> c) -> b ~> c
I'll fix (~->) to mean Kleisli Maybe so you can see it in action:
{-# LANGUAGE TypeOperators #-}
import Control.Arrow
type (~->) = Kleisli Maybe
g :: Integer ~-> Integer
g = Kleisli Just >>> arr (*2)
giving
ghci> runKleisli g 10
Just 20
Like do notation, but with input as well as output. (GHC)
GHC implements the equivalent of do notation, proc notation, which lets you do
output <- arrow -< input
You're used to output <- monad but now there's the arrow -< input notation. Just as with Monads, you don't do <- on the last line, you don't do that in proc notation either.
Let's use the Maybe versions of tail and read from safe to illustrate the notation (and advertise safe).
{-# LANGUAGE Arrows #-}
import Control.Arrow
import Safe
this = proc inputList -> do
digits <- Kleisli tailMay -< inputList
number <- Kleisli readMay -<< digits
arr (*10) -<< number
Notice I've used the -<< variant of -<, which lets you use output as input by bringing things on the left of <- into scope at the right of -<.
Clearly this is equivalent to Kleisli tailMay >>> Kleisli readMay >>> arr (*10), but it's just (!) to give you the idea.
ghci> runKleisli this "H1234" -- works
Just 1234
ghci> runKleisli this "HH1234" -- readMay fails
Nothing
ghci> runKleisli this "" -- tailMay fails
Nothing
ghci> runKleisli this "10" -- works
Just 0
All that ()
Like I said, we use () if we don't have input, and as we do in Monad, return it if we don't need to output anything.
You'll see () in proc notation examples too:
thing = proc x -> do
this <- thing1 -< ()
() <- thing2 -< x
returnA -< this
First we need an arrow with the same semantics as the Maybe monad. We could define it from scratch, but the easiest way is to wrap the Maybe monad into Kleisli:
type MaybeArrow = Kleisli Maybe
Then we'll also need a way how to run this monad to extract the result:
runMaybeArrow :: MaybeArrow () a -> Maybe a
runMaybeArrow = flip runKleisli ()
Also it'll be handy to have a way how to create a constant arrow from a given value (which just ignores its input):
val :: (Arrow a) => c -> a b c
val = arr . const
And finally, we get:
g' = runMaybeArrow (val 5 >>> arr f)

Is there a combinator that applies multiple functions to a single value in Haskell?

For example, suppose I have the following functions:
foo :: Monad f => f a
bar :: Monad f => a -> f b
baz :: Monad f => a -> f c
qux :: Monad f => a -> f d
And I only want to return the result of qux, e.g. g :: Monad f => f a -> f d,
where g calls bar and baz for their side-effects, perhaps.
Is there a way to construct g without explicitly applying each function to the result of foo? Somewhat similar to how (&&&) works, or (<*>) I suppose.
Here's a possible solution using the Monad instance for ((->) r). This works nicely, and scales to as many function applications as neccessary.
g :: Monad m => m a -> m b
g foo = foo >>= bar .&. baz .&. qux
where (.&.) = liftM2 (>>)
I'm assuming that a b c and d are in fact not supposed to be type variables and instead you meant more like
data A
data B
data C
data D
Because otherwise you're asking for a function of type forall a b. a -> b which is impossible to meaningfully create.
k = Kleisli
a &^& b = a &&& b >>> arr snd
g = runKleisli $ k bar &^& k baz &^& k quux
is a simple way to do this. it uses the kleisli arrow which wraps around a Monad to lift it into arrow land. I'm not aware of any nice combinators that accomplish &^& in a predefined way but it's pretty trivial to define.
The nice thing is that this scales trivially and is pointfree
g = runKleisli $ k f &^& k f' &^& k f'' &^& k f''' ....

Resources