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
Related
I'm using the FreeT type from the free library to write this function which "runs" an underlying StateT:
runStateFree
:: (Functor f, Monad m)
=> s
-> FreeT f (StateT s m) a
-> FreeT f m (a, s)
runStateFree s0 (FreeT x) = FreeT $ do
flip fmap (runStateT x s0) $ \(r, s1) -> case r of
Pure y -> Pure (y, s1)
Free z -> Free (runStateFree s1 <$> z)
However, I'm trying to convert it to work on FT, the church-encoded version, instead:
runStateF
:: (Functor f, Monad m)
=> s
-> FT f (StateT s m) a
-> FT f m (a, s)
runStateF s0 (FT x) = FT $ \ka kf -> ...
but I'm not quite having the same luck. Every sort of combination of things I get seems to not quite work out. The closest I've gotten is
runStateF s0 (FT x) = FT $ \ka kf ->
ka =<< runStateT (x pure (\n -> _ . kf (_ . n)) s0
But the type of the first hole is m r -> StateT s m r and the type the second hole is StateT s m r -> m r...which means we necessarily lose the state in the process.
I know that all FreeT functions are possible to write with FT. Is there a nice way to write this that doesn't involve round-tripping through FreeT (that is, in a way that requires explicitly matching on Pure and Free)? (I've tried manually inlining things but I don't know how to deal with the recursion using different ss in the definition of runStateFree). Or maybe this is one of those cases where the explicit recursive data type is necessarily more performant than the church (mu) encoding?
Here's the definition. There are no tricks in the implementation itself. Don't think and make it type check. Yes, at least one of these fmap is morally questionable, but the difficulty is actually to convince ourselves it does the Right thing.
runStateF
:: (Functor f, Monad m)
=> s
-> FT f (StateT s m) a
-> FT f m (a, s)
runStateF s0 (FT run) = FT $ \return0 handle0 ->
let returnS a = StateT (\s -> fmap (\r -> (r, s)) (return0 (a, s)))
handleS k e = StateT (\s -> fmap (\r -> (r, s)) (handle0 (\x -> evalStateT (k x) s) e))
in evalStateT (run returnS handleS) s0
We have two stateless functions (i.e., plain m)
return0 :: a -> m r
handle0 :: forall x. (x -> m r) -> f x -> m r
and we must wrap them in two stateful (StateT s m) variants with the signatures below. The comments that follow give some details about what is going on in the definition of handleS.
returnS :: a -> StateT s m r
handleS :: forall x. (x -> StateT s m r) -> f x -> StateT s m r
-- 1. -- ^ grab the current state 's' here
-- 2. -- ^ call handle0 to produce that 'm'
-- 3. ^ here we will have to provide some state 's': pass the current state we just grabbed.
-- The idea is that 'handle0' is stateless in handling 'f x',
-- so it is fine for this continuation (x -> StateT s m r) to get the state from before the call to 'handle0'
There is an apparently dubious use of fmap in handleS, but it is valid as long as run never looks at the states produced by handleS. It is almost immediately thrown away by one of the evalStateT.
In theory, there exist terms of type FT f (StateT s m) a which break that invariant. In practice, that almost certainly doesn't occur; you would really have to go out of your way to do something morally wrong with those continuations.
In the following complete gist, I also show how to test with QuickCheck that it is indeed equivalent to your initial version using FreeT, with concrete evidence that the above invariant holds:
https://gist.github.com/Lysxia/a0afa3ca2ea9e39b400cde25b5012d18
I'd say that no, as even something as simple as cutoff converts to FreeT:
cutoff :: (Functor f, Monad m) => Integer -> FT f m a -> FT f m (Maybe a)
cutoff n = toFT . FreeT.cutoff n . fromFT
In general, you're probably looking at:
improve :: Functor f => (forall m. MonadFree f m => m a) -> Free f a
Improve the asymptotic performance of code that builds a free monad with only binds and returns by using F behind the scenes.
I.e. you'll construct Free efficiently, but then do whatever you need to do with Free (maybe again, by improveing).
I looked hard to see if this may be a duplicate question but couldn't find anything that addressed specifically this. My apologies if there actually is something.
So, I get how lift works, it lifts a monadic action (fully defined) from the outer-most transformer into the transformed monad. Cool.
But what if I want to apply a (>>=) from one level under the transformer into the transformer? I'll explain with an example.
Say MyTrans is a MonadTrans, and there is also an instance Monad m => Monad (MyTrans m). Now, the (>>=) from this instance will have this signature:
instance Monad m => Monad (MyTrans m) where
(>>=) :: MyTrans m a -> (a -> MyTrans m b) -> MyTrans m b
but what I need is something like this:
(>>=!) :: Monad m => MyTrans m a -> (m a -> MyTrans m b) -> MyTrans m b
In general:
(>>=!) :: (MonadTrans t, Monad m) => t m a -> (m a -> t m b) -> t m b
It looks like a combination of the original (>>=) and lift, except it really isn't. lift can only be used on covariant arguments of type m a to transform them into a t m a, not the other way around. In other words, the following has the wrong type:
(>>=!?) :: Monad m => MyTrans m a -> (a -> m b) -> MyTrans m b
x >>=!? f = x >>= (lift . f)
Of course a general colift :: (MonadTrans t, Monad m) => t m a -> m a makes absolutely zero sense, because surely the transformer is doing something that we cannot just throw away like that in all cases.
But just like (>>=) introduces contravariant arguments into the monad by ensuring that they will always "come back", I thought something along the lines of the (>>=!) function would make sense: Yes, it in some way makes an m a from a t m a, but only because it does all of this within t, just like (>>=) makes an a from an m a in some way.
I've thought about it and I don't think (>>=!) can be in general defined from the available tools. In some sense it is more than what MonadTrans gives. I haven't found any related type classes that offer this either. MFunctor is related but it is a different thing, for changing the inner monad, but not for chaining exclusively transformer-related actions.
By the way, here is an example of why you would want to do this:
EDIT: I tried to present a simple example but I realized that that one could be solved with the regular (>>=) from the transformer. My real example (I think) cannot be solved with this. If you think every case can be solved with the usual (>>=), please do explain how.
Should I just define my own type class for this and give some basic implementations? (I'm interested in StateT, and I'm almost certain it can be implemented for it) Am I doing something in a twisted way? Is there something I overlooked?
Thanks.
EDIT: The answer provided by Fyodor matches the types, but does not do what I want, since by using pure, it is ignoring the monadic effects of the m monad. Here is an example of it giving the wrong answer:
Take t = StateT Int and m = [].
x1 :: StateT Int [] Int
x1 = StateT (\s -> [(1,s),(2,s),(3,s)])
x2 :: StateT Int [] Int
x2 = StateT (\s -> [(1,s),(2,s),(3,s),(4,s))])
f :: [Int] -> StateT Int [] Int
f l = StateT (\s -> if (even s) then [] else (if (even (length l)) then (fmap (\z -> (z,z+s)) l) else [(123,123)]))
runStateT (x1 >>= (\a -> f (pure a))) 1 returns [(123,123),(123,123),(123,123)] as expected, since both 1 is odd and the list in x1 has odd length.
But runStateT (x2 >>= (\a -> f (pure a))) 1 returns [(123,123),(123,123),(123,123),(123,123)], whereas I would have expected it to return [(1,2),(2,3),(3,4),(4,5)], since the 1 is odd and the length of the list is even. Instead, the evaluation of f is happening on the lists [(1,1)], [(2,1)], [(3,1)] and [(4,1)] independently, due to the pure call.
This can be very trivially implemented via bind + pure. Consider the signature:
(>>=!) :: (Monad m, MonadTrans t) => t m a -> (m a -> t m a) -> t m a
If you use bind on the first argument, you get yourself a naked a, and since m is a Monad, you can trivially turn that naked a into an m a via pure. Therefore, the straightforward implementation would be:
(>>=!) x f = x >>= \a -> f (pure a)
And because of this, bind is always strictly more powerful than your proposed new operation (>>=!), which is probably the reason it doesn't exist in the standard libraries.
I think it may be possible to propose more clever interpretations of (>>=!) for some specific transformers or specific underlying monads. For example, if m ~ [], one might imagine passing the whole list as m a instead of its elements one by one, as my generic implementation above would do. But this sort of thing seems too specific to be implemented in general.
If you have a very specific example of what you're after, and you can show that my above general implementation doesn't work, then perhaps I can provide a better answer.
Ok, to address your actual problem from the comments:
I have a function f :: m a -> m b -> m c that I want to transform into a function ff :: StateT s m a -> StateT s m b -> StateT s m c
I think looking at this example may illustrate the difficulty better. Consider the required signature:
liftish :: Monad m => (m a -> m b -> m c) -> StateT m a -> StateT m b -> StateT m c
Presumably, you'd want to keep the effects of m that are already "imprinted" within the StateT m a and StateT m b parameters (because if you don't - my simple solution above will work). To do this, you can "unwrap" the StateT via runStateT, which will get you m a and m b respectively, which you can then use to obtain m c:
liftish f sa sb = do
s <- get
let ma = fst <$> runStateT sa s
mb = fst <$> runStateT sb s
lift $ f ma mb
But here's the trouble: see those fst <$> in there? They are throwing away the resulting state. The call to runStateT sa s results not only in the m a value, but also in the new, modified state. And same goes for runStateT sb s. And presumably you'd want to get the state that resulted from runStateT sa and pass it to runStateT sb, right? Otherwise you're effectively dropping some state mutations.
But you can't get to the resulting state of runStateT sa, because it's "wrapped" inside m. Because runStateT returns m (a, s) instead of (m a, s). If you knew how to "unwrap" m, you'd be fine, but you don't. So the only way to get that intermediate state is to run the effects of m:
liftish f sa sb = do
s <- get
(c, s'') <- lift $ do
let ma = runStateT sa s
(_, s') <- ma
let mb = runStateT sb s'
(_, s'') <- mb
c <- f (fst <$> ma) (fst <$> mb)
pure (c, s'')
put s''
pure c
But now see what happens: I'm using ma and mb twice: once to get the new states out of them, and second time by passing them to f. This may lead to double-running effects or worse.
This problem of "double execution" will, I think, show up for any monad transformer, simply because the transformer's effects are always wrapped inside the underlying monad, so you have a choice: either drop the transformer's effects or execute the underlying monad's effects twice.
I think what you "really want" is
(>>>==) :: MyTrans m a -> (forall b. m b -> MyTrans n b) -> MyTrans n a
-- (=<<) = flip (>>=) is nicer to think about, because it shows that it's a form of function application
-- so let's think about
(==<<<) :: (forall a. m b -> MyTrans n b) -> (forall a. MyTrans m a -> MyTrans n a)
-- hmm...
type (~>) a b = forall x. a x -> b x
(==<<<) :: (m ~> MyTrans n) -> MyTrans m ~> MyTrans n
-- look familiar?
That is, you are describing monads on the category of monads.
class MonadTrans t => MonadMonad t where
-- returnM :: m ~> t m
-- but that's just lift, therefore the MonadTrans t superclass
-- note: input must be a monad homomorphism or else all bets are off
-- output is also a monad homomorphism
(==<<<) :: (Monad m, Monad n) => (m ~> t n) -> t m ~> t n
instance MonadMonad (StateT s) where
-- fairly sure this is lawful
-- EDIT: probably not
f ==<<< StateT x = do
(x, s) <- f <$> x <$> get
x <$ put s
However, making your example work is just not going to happen. It is too unnatural. StateT Int [] is the monad for programs that nondeterministically evolve the state. It is an important property of that monad that each "parallel universe" receives no communication from the others. The specific operation you are performing will probably not be provided by any useful typeclass. You can only do part of it:
f :: [] ~> StateT Int []
f l = StateT \s -> if odd s && even (length l) then fmap (\x -> (x, s)) l else []
f ==<<< x1 = []
f ==<<< x2 = [(1,1),(2,1),(3,1),(4,1)]
Explain about a "duplicate"
Someone point to Is this a case for foldM? as a possible duplicate. Now, I have a strong opinion that, two questions that can be answered with identical answers are not necessarily duplicates! "What is 1 - 2" and "What is i^2" both yields "-1", but no, they are not duplicate questions. My question (which is already answered, kind of) was about "whether the function iterateM exists in Haskell standard library", not "How to implement a chained monad action".
The question
When I write some projects, I found myself writing this combinator:
repeatM :: Monad m => Int -> (a -> m a) -> a -> m a
repeatM 0 _ a = return a
repeatM n f a = (repeatM (n-1) f) =<< f a
It just performs a monadic action n times, feeding the previous result into the next action. I tried some hoogle search and some Google search, and did not find anything that comes with the "standard" Haskell. Is there such a formal function that is predefined?
You can use foldM, e.g.:
import Control.Monad
f a = do print a; return (a+2)
repeatM n f a0 = foldM (\a _ -> f a) a0 [1..n]
test = repeatM 5 f 3
-- output: 3 5 7 9 11
Carsten mentioned replicate, and that's not a bad thought.
import Control.Monad
repeatM n f = foldr (>=>) pure (replicate n f)
The idea behind this is that for any monad m, the functions of type a -> m b form the Kleisli category of m, with identity arrows
pure :: a -> m a
(also called return)
and composition operator
(<=<) :: (b -> m c) -> (a -> m b) -> a -> m c
f <=< g = \a -> f =<< g a
Since were actually dealing with a function of type a -> m a, we're really looking at one monoid of the Kleisli category, so we can think about folding lists of these arrows.
What the code above does is fold the composition operator, flipped, into a list of n copies of f, finishing off with an identity as usual. Flipping the composition operator actually puts us into the dual category; for many common monads, x >=> y >=> z >=> w is more efficient than w <=< z <=< y <=< x; since all the arrows are the same in this case, it seems we might as well. Note that for the lazy state monad and likely also the reader monad, it may be better to use the unflipped <=< operator; >=> will generally be better for IO, ST s, and the usual strict state.
Notice: I am no category theorist, so there may be errors in the explanation above.
I find myself wanting this function often, I wish it had a standard name. That name however would not be repeatM - that would be for an infinite repeat, like forever if it existed, just for consistency with other libraries (and repeatM is defined in some libraries that way).
Just as another perspective from the answers already given, I point out that (s -> m s) looks a bit like an action in a State monad with state type s.
In fact, it is isomorphic to StateT s m () - an action which returns no value, because all the work it does is encapsulated in the way it changes the state. In this monad, the function you wanted really is replicateM. You can write it this way in haskell although it probably looks uglier than just writing it directly.
First convert s -> m s to the equivalent form which StateT uses, adding the information-free (), using liftM to map a function over the return type.
> :t \f -> liftM (\x -> ((),x)) . f
\f -> liftM (\x -> ((),x)) . f :: Monad m => (a -> m t) -> a -> m ((), t)
(could have used fmap but the Monad constraint seems clearer here; could have used TupleSections if you like; if you find do notation easier to read it is simply \f s -> do x <- f s; return ((),s) ).
Now this has the right type to wrap up with StateT:
> :t StateT . \f -> liftM (\x -> ((),x)) . f
StateT . \f -> liftM (\x -> ((),x)) . f :: Monad m => (s -> m s) -> StateT s m ()
and then you can replicate it n times, using the replicateM_ version because the returned list [()] from replicateM would not be interesting:
> :t \n -> replicateM_ n . StateT . \f -> liftM (\x -> ((),x)) . f
\n -> replicateM_ n . StateT . \f -> liftM (\x -> ((),x)) . f :: Monad m => Int -> (s -> m s) -> StateT s m ()
and finally you can use execStateT to go back to the Monad you were originally working in:
runNTimes :: Monad m => Int -> (s -> m s) -> s -> m s
runNTimes n act =
execStateT . replicateM_ n . StateT . (\f -> liftM (\x -> ((),x)) . f) $ act
So >>= :: m a -> (a -> m b) -> m b and >> :: m a -> m b -> m b.
whereas <* :: f a -> f b -> f a.
But I want something that does m a -> (a -> m b) -> m a, i.e. actually discards the computation result and keeps the original. In my case, this computation result is just an IO operation that returns () so I just need to pass the original value along.
Is there such a function? If not, how do I compose one? Haven't managed to figure it out. Thanks!
discardResult mx mf = do x <- mx
mf x
return x
Though jozefg's solution is simpler.
discard :: Monad m => m a -> (a -> m b) -> m a
discard g f = g >>= ((>>) <$> f <*> return)
Uses the Applicative instance of (->) to make it a little shorter, but is otherwise equivalent to Alexey's answer. Of course this requires Control.Applicative but since you mentioned <* I figured you already had that one.
E.g: discard getLine print reads a line, prints it and then returns the string read.
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)