Evaluation of the expression str ab = ((.). (.)) (0 -) (+) 1 2

Could you explain to me how the following expression works:

str ab = ((.).(.)) (0 -) (+) 1 2 

I checked it, and GHCi said it was -3 , but I do not understand why.

I also checked the following:

 *Main> :t ((.).(.)) ((.).(.)) :: (b -> c) -> (a -> a1 -> b) -> a -> a1 -> c 

but it didn’t help me.

Any idea?

+4
source share
3 answers

The (.).(.) Operator is sometimes assigned an alias:

 (.:) = (.).(.) 

You can view it as (.) , Only it works when the second function takes two arguments. So this works, for example:

 sqrtsum = sqrt .: (+) -- sqrtsum 4 5 ==> 3.0 

It takes two numbers, sums them up, and then takes the square root of the sum. The alias type .: Makes visual sense, since you can imagine that a colon representing a function of two arguments is associated with a function of one argument.

If you want, you can view the type signature (.) As follows:

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

This means that (.) Performs two functions a -> b and b -> c and "connects them together" and returns a function from a directly to c . The operator (.:) works similarly - you can write its signature like

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

What he does is that for one function a1 -> a2 -> b and one function b -> c it returns a function that goes directly from a1 and a2 to c .

If you want to check this type for yourself, you can go your way to (.:) with a signature for (.) . I will not do this for you, partly because it can become a wall of text and partly because it is a great exercise for you to reason about your code! If you need a place to start, remember that

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

In expression

 (.).(.) 

which can also be written as

 (.) (.) (.) 

the two argument functions in (.) ( a -> b and b -> c ) are themselves (.) ), so you can replace a lot of a and b and c with what they actually represent!

+9
source

You will learn most if you expose lambda terms manually. Or if you are lazy, use a tool.

Anyway, here it is:

 dot = λf.λg.λx.f (gx) dot dot dot (0 -) + 1 2 ⇒ (λg.λx.dot (gx)) dot (0 -) + 1 2 ⇒ (λx.dot (dot x)) (0 -) + 1 2 ⇒ dot (dot (0 -)) + 1 2 ⇒ (λg.λx.dot (0 -) (gx)) + 1 2 ⇒ (λx.dot (0 -) (+ x)) 1 2 ⇒ dot (0 -) (+ 1) 2 ⇒ (λg.λx.0 - (gx)) (+ 1) 2 ⇒ (λx.0 - (+ 1 x)) 20 - (+ 1 2) ⇒ 0 - 3 
+8
source

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

Values: (0 -)_______(+)_______________1___2

1 is a , 2 is a1 , (+) is (a -> a1 -> b) .. applied (+) to 1 and 2 you get 3, which is now the value of b .

(0 -) , (b -> c) , apply 3 (which was b above) to this you get (0-3), i.e. -3 , which is the value of c , and this whole function returns c therefore 3 - final answer.

+7
source

Source: https://habr.com/ru/post/1499772/


All Articles