Haskell function composition operator of type (c→d) → (a→b→c) → (a→b→d)

后端 未结 6 682
耶瑟儿~
耶瑟儿~ 2020-11-28 04:21

Ordinary function composition is of the type

(.) :: (b -> c) -> (a -> b) -> a -> c

I figure this should generalize to types

6条回答
  •  忘掉有多难
    2020-11-28 04:40

    My preferred implementation for this is

    fmap . fmap :: (Functor f, Functor f1) => (a -> b) -> f (f1 a) -> f (f1 b)
    

    If only because it is fairly easy to remember.

    When instantiating f and f1 to (->) c and (->) d respectively you get the type

    (a -> b) -> (c -> d -> a) -> c -> d -> b
    

    which is the type of

    (.) . (.) ::  (b -> c) -> (a -> a1 -> b) -> a -> a1 -> c
    

    but it is a bit easier to rattle off the fmap . fmap version and it generalizes to other functors.

    Sometimes this is written fmap fmap fmap, but written as fmap . fmap it can be more readily expanded to allow more arguments.

    fmap . fmap . fmap 
    :: (Functor f, Functor g, Functor h) => (a -> b) -> f (g (h a)) -> f (g (h b))
    
    fmap . fmap . fmap . fmap 
    :: (Functor f, Functor g, Functor h, Functor i) => (a -> b) -> f (g (h (i a))) -> f (g (h (i b))
    

    etc.

    In general fmap composed with itself n times can be used to fmap n levels deep!

    And since functions form a Functor, this provides plumbing for n arguments.

    For more information, see Conal Elliott's Semantic Editor Combinators.

提交回复
热议问题