Composing function composition: How does (.).(.) work?

后端 未结 7 1635
温柔的废话
温柔的废话 2020-11-29 06:36

(.) takes two functions that take one value and return a value:

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

7条回答
  •  旧时难觅i
    2020-11-29 06:56

    (Read my answer on function composition, $ operator and point-free style first.)

    Imagine you have a simple function: it adds up 2 numbers and then negates the result. We'll call it foo:

    foo a b = negate (a + b)
    

    Now let's make it point-free step by step and see what we end up with:

    foo a b = negate $ a + b
    foo a b = negate $ (+) a b
    foo a b = negate $ (+) a $ b
    foo a b = negate . (+) a $ b
    foo a   = negate . (+) a -- f x = g x is equivalent to f = g
    foo a   = (.) negate ((+) a) -- any infix operator is just a function
    foo a   = (negate.) ((+) a) -- (2+) is the same as ((+) 2)
    foo a   = (negate.) $ (+) a
    foo a   = (negate.) . (+) $ a
    foo     = (negate.) . (+)
    foo     = ((.) negate) . (+)
    foo     = (.) ((.) negate) (+) -- move dot in the middle in prefix position
    foo     = ((.) ((.) negate)) (+) -- add extra parentheses
    

    Now let's analyze expression (.) ((.) negate) more closely. It's a partial application of (.) function, whose first argument is ((.) negate). Can we transform it even further? Yes we can:

    (.) ((.) negate)
    (.) . (.) $ negate -- because f (f x) is the same as (f . f) x
    (.)(.)(.) $ negate
    ((.)(.)(.)) negate
    

    (.).(.) is equivalent to (.)(.)(.), because in the 1st expression, the dot in the middle can be moved in prefix position and surrounded with parentheses, which gives rise to the 2nd expression.

    Now we can rewrite our foo function:

    foo = ((.).(.)) negate (+)
    foo = ((.)(.)(.)) negate (+) -- same as previous one
    foo = negate .: (+)
      where (.:) = (.).(.)
    

    Now you know that (.).(.) is equivalent to (\f g x y -> f (g x y)):

    (\f g x y -> f (g x y)) negate (+) 2 3 -- returns -5
    ((.).(.)) negate (+) 2 3 -- returns -5
    

提交回复
热议问题