Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell (a -> m a) -> m (a -> a) -> m (a -> a)

Tags:

haskell

monads

I've been digging into Haskell for the past months, I've run into a situation with monads that I am not quite sure how to handle.

I have one value of type a -> m a and a second of type m (a -> a) and I need to compose them such that the result of the first ends up as the input into the of the second and produces a m (a -> a) if possible. I've been stuck on this for the past day now and I'm not wrapping my head around it. I suppose that I am looking for a function like (a -> m a) -> m (a -> a) -> m (a -> a). I can provide a more concrete example if it makes more sense.

like image 271
Ben Doerr Avatar asked Apr 05 '16 20:04

Ben Doerr


People also ask

What does >> mean in Haskell?

Essentially, a >> b can be read like "do a then do b , and return the result of b ". It's similar to the more common bind operator >>= .

What is applicative Haskell?

In Haskell, an applicative is a parametrized type that we think of as being a container for data of that type plus two methods pure and <*> . Consider a parametrized type f a . The pure method for an applicative of type f has type. pure :: a -> f a. and can be thought of as bringing values into the applicative.

Do expressions Haskell?

As a syntactical convenience, do notation does not add anything essential, but it is often preferable for clarity and style. However, do is not needed for a single action, at all. The Haskell "Hello world" is simply: main = putStrLn "Hello world!"

What is a functor in Haskell?

Functor in Haskell is a kind of functional representation of different Types which can be mapped over. It is a high level concept of implementing polymorphism. According to Haskell developers, all the Types such as List, Map, Tree, etc. are the instance of the Haskell Functor.


1 Answers

You can't do this, in general. The problem is your result type: m (a -> a). This is a single monadic action which produces a function; but your first input has the form a -> m a, which (potentially) produces a different monadic action for each argument. So, for example, for the [] monad [a -> a] is list of functions with a fixed length, whereas a -> [a] can have a different length for each argument. So there's no way to 'push' the function type back into the m in general; see What is the general case of QuickCheck's promote function? for a related SO question.

If a -> m a would work for what you need, then you can turn your m (a -> a) argument into a -> m a using

\ x -> fmap ($ x) af

and use >=> (or <=<, it's not clear from your types) to compose the functions together.

like image 177
Jonathan Cast Avatar answered Sep 29 '22 00:09

Jonathan Cast