Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Evaluation of expression str a b = ((.).(.)) (0 -) (+) 1 2 [duplicate]

Could you explain to me how the following expression works:

str a b = ((.).(.)) (0 -) (+) 1 2

I have checked it and GHCi said that it is -3 but I don't understand why.

I checked as well the following:

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

but it doesn't helped me.

Any idea?

like image 440
JosephConrad Avatar asked Nov 29 '22 08:11

JosephConrad


2 Answers

The operator (.).(.) is sometimes given 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

This will take two numbers, sum them and then take the square root of the sum. The .: alias sort of makes visual sense, as you can imagine the colon representing the function of two arguments being connected to the function of one argument.

If you want to, you can view the type signature of (.) like this:

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

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

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

What it does is that it takes one function a1 -> a2 -> b and one function b -> c and it gives you back a function that goes directly from a1 and a2 to c.

If you want to verify this type for yourself, you can work your way to (.:) with the signature for (.). I will not do this for you, in part because it might end up being a wall of text and in part because it's a great exercise for you in reasoning about your code! If you need a place to start, remember that

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

In the expression

(.).(.)

which can also be written as

(.) (.) (.)

the two argument functions to (.) (a -> b and b -> c) are both (.) themselves – so you get to replace a lot of as and bs and cs with what they really represent!

like image 74
kqr Avatar answered Dec 05 '22 02:12

kqr


You'll learn the most if you expand the lambda terms by hand. Or, if you're lazy, use a tool.

Anyway, here it is:

dot = λf.λg.λx.f (g x)

dot dot dot (0 -) + 1 2
⇒   (λg.λx.dot (g x)) dot (0 -) + 1 2
⇒   (λx.dot (dot x)) (0 -) + 1 2
⇒   dot (dot (0 -)) + 1 2
⇒   (λg.λx.dot (0 -) (g x)) + 1 2
⇒   (λx.dot (0 -) (+ x)) 1 2
⇒   dot (0 -) (+ 1) 2
⇒   (λg.λx.0 - (g x)) (+ 1) 2
⇒   (λx.0 - (+ 1 x)) 2
⇒   0 - (+ 1 2)
⇒   0 - 3
like image 29
phipsgabler Avatar answered Dec 05 '22 03:12

phipsgabler