Is there any intuition to understand join two functions in Monad?

前端 未结 3 874
醉话见心
醉话见心 2021-02-13 17:58

join is defined along with bind to flatten the combined data structure into single structure.

From type system view, (+) 7 :: Num a =>

3条回答
  •  清歌不尽
    2021-02-13 18:24

    how to get some intuition about it instead of just relying on type system?

    I'd rather say that relying on the type system is a great way to build a specific sort of intuition. The type of join is:

    join :: Monad m => m (m a) -> m a
    

    Specialised to (->) r, it becomes:

    (r -> (r -> a)) -> (r -> a)
    

    Now let's try to define join for functions:

    -- join :: (r -> (r -> a)) -> (r -> a)
    join f = -- etc.
    

    We know the result must be a r -> a function:

    join f = \x -> -- etc.
    

    However, we do not know anything at all about what the r and a types are, and therefore we know nothing in particular about f :: r -> (r -> a) and x :: r. Our ignorance means there is literally just one thing we can do with them: passing x as an argument, both to f and to f x:

    join f = \x -> f x x
    

    Therefore, join for functions passes the same argument twice because that is the only possible implementation. Of course, that implementation is only a proper monadic join because it follows the monad laws:

    join . fmap join = join . join
    join . fmap return = id
    join . return = id
    

    Verifying that might be another nice exercise.

提交回复
热议问题