Function application as identiity Monad: how is it an instance of the Monad typeclass?

StackOverflow https://stackoverflow.com/questions/22934032

  •  29-06-2023
  •  | 
  •  

Question

I am reading The Craft of Functional Programming (2nd edition), where it is briefly mentioned on page 404 that function application is also a Monad, the author calls it the identity Monad.

However I have difficulty imagining how function application can be made an instance of the type class Monad in Haskell in the same spirit as the Maybe data structure is made an instance of the Monad type class.

This leads me also to an other question: How is the function application a type constructor (in the same way as Maybe is)?

Could someone please give some insight into this mystery ?

Was it helpful?

Solution

The function application is not the monad per se, it's the bind in the Identity monad.

newtype Identity a = Identity { runIdentity :: a }
instance Monad Identity where
    return = Identity
    (Identity a) >>= f = f a -- :: Identity a -> (a -> Identity b) -> Identity b
    join (Identity (Identity a)) = Identity a
    fmap f (Identity a) = Identity $ f a

So if you lift all your functions and values into the identity monad, you can use do-notation and it'll just be a lot of bookkeeping around ordinary function application.

You should not confuse this with the Monad instance for the type (->) a which is isomorphic to the reader Monad: newtype Reader a b = Reader { runReader :: a -> b }.

OTHER TIPS

[EDIT: I have not read this book, and having seem nimish's answer it seems I have misinterpreted your question]

r -> a can also be written (->) r a, and it is the (->) r type constructor (which you can read as "functions from r") that can be given a monad instance. To define an instance we need to provide

return :: a -> (r -> a)
(>>=)  :: (r -> a) -> (a -> (r -> b)) -> r -> b

The former is easy. For the latter, here's a hint. When fully applied (>>=) takes three arguments, of types r -> a, a -> r -> b and r. It should now be clear how to combine these to get a b.

Your knowledge will also benefit from implementing

join :: (r -> (r -> a)) -> (r -> a)

A note: I don't understand why anyone would call this the "identity monad". The identity monad is usually newtype Identity a = Identity a. The monad of "functions from r" is (isomorphic to) the Reader monad.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top