Haskell function composition, type of (.)(.) and how it's presented

自闭症网瘾萝莉.ら 提交于 2019-11-29 16:10:09

问题


So i know that:

(.) = (f.g) x = f (g x)

And it's type is (B->C)->(A->B)->A->C But what about:

(.)(.) = _? = _?

How this is represented? I thought of:

(.)(.) = (f.g)(f.g)x = f(g(f(g x))) // this
(.)(.) = (f.g.h)x = f(g(h x)) // or this

But as far as i tried to get type of it, it's not correct to what GHCi tells me. So what are both "_?"

Also - what does function/operator $ do?


回答1:


First off, you're being sloppy with your notation.

(.) = (f.g) x = f (g x)  -- this isn't true

What is true:

(.) f g x = (f.g) x = f (g x)
(.) = \f g x -> f (g x)

And its type is given by

(.) :: (b -> c) -> (a -> b) -> a -> c
       -- n.b. lower case, because they're type *variables*

Meanwhile

(.)(.) :: (a -> b -> d) -> a -> (c -> b) -> c -> d
          -- I renamed the variables ghci gave me

Now let's work out

(.)(.) = (\f' g' x' -> f' (g' x')) (\f g x -> f (g x))
       = \g' x' -> (\f g x -> f (g x)) (g' x')
       = \g' x' -> \g x -> (g' x') (g x)
       = \f y -> \g x -> (f y) (g x)
       = \f y g x -> f y (g x)
       = \f y g x -> (f y . g) x
       = \f y g -> f y . g

And ($)?

($) :: (a -> b) -> a -> b
f $ x = f x

($) is just function application. But whereas function application via juxtaposition is high precedence, function application via ($) is low precedence.

square $ 1 + 2 * 3 = square (1 + 2 * 3)
square 1 + 2 * 3 = (square 1) + 2 * 3  -- these lines are different



回答2:


As dave4420 mentions,

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

So what is the type of (.) (.)? dave4420 skips that part, so here it is: (.) accepts a value of type b -> c as its first argument, so

(.) :: (   b     ->       c             ) -> (a -> b) -> a -> c
(.) ::  (d -> e) -> ((f -> d) -> f -> e)

so we have b ~ d->e and c ~ (f -> d) -> f -> e, and the resulting type of (.)(.) is (a -> b) -> a -> c. Substituting, we get

(a -> d -> e) -> a -> (f -> d) -> f -> e

Renaming, we get (a -> b -> c) -> a -> (d -> b) -> d -> c. This is a function f that expects a binary function g, a value x, a unary function h and another value y:

f g x h y = g x (h y)

That's the only way this type can be realized: g x :: b -> c, h y :: b and so g x (h y) :: c, as needed.

Of course in Haskell, a "unary" function is such that expects one or more arguments; similarly a "binary" function is such that expects two or more arguments. But not less than two (so using e.g. succ is out of the question).


We can also tackle this by writing equations, combinators-style1. Equational reasoning is easy:

(.) (.) x y z w q = 
((.) . x) y z w q =
(.) (x y) z w q =
(x y . z) w q =
x y (z w) q 

We just throw as much variables as needed into the mix and then apply the definition back and forth. q here was an extra, so we can throw it away and get the final definition,

_BB x y z w = x y (z w)

(coincidentally, (.) is known as B-combinator).


1a b c = (\x -> ... body ...) is equivalent to a b c x = ... body ..., and vice versa, provided that x does not appear among {a,b,c}.



来源:https://stackoverflow.com/questions/16202289/haskell-function-composition-type-of-and-how-its-presented

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!