Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explain (.)(.) to me

Diving into Haskell, and while I am enjoying the language I'm finding the pointfree style completely illegible. I've come a across this function which only consists of these ASCII boobies as seen below.

f = (.)(.)

And while I understand its type signature and what it does, I can't for the life of me understand why it does it. So could someone please write out the de-pointfreed version of it for me, and maybe step by step work back to the pointfree version sorta like this:

f g x y = (g x) + y   
f g x = (+) (g x)    
f g = (+) . g    
f = (.) (+)
like image 838
Erik Avatar asked May 21 '18 15:05

Erik


People also ask

Why explain to me and not explain me?

The correct answer here is “Explain to me.” This is due to the fact the verb “explain” (to explain) is a ditransitive verb. And, as such, it takes a direct object and an indirect object. Actually, all ditransitive verbs normally take two different objects: a direct object and an indirect object.

Is it correct to explain?

Explain it to me. Correct. Explain me. Incorrect / You won't hear it.

How explain meaning?

explain, expound, explicate, elucidate, interpret mean to make something clear or understandable. explain implies a making plain or intelligible what is not immediately obvious or entirely known. explain the rules expound implies a careful often elaborate explanation.

Can you explain or could you explain?

'Could you' is more polite than 'Can you' and it sounds better - particularly if you are asking someone to do something for you.


2 Answers

Generally (?) (where ? stands for an arbitrary infix operator) is the same as \x y -> x ? y. So we can rewrite f as:

f = (\a b -> a . b) (\c d -> c . d)

Now if we apply the argument to the function, we get:

f = (\b -> (\c d -> c . d) . b)

Now b is just an argument to f, so we can rewrite this as:

f b = (\c d -> c . d) . b

The definition of . is f . g = \x -> f (g x). If replace the outer . with its definition, we get:

f b = \x -> (\c d -> c . d) (b x)

Again we can turn x into a regular parameter:

f b x = (\c d -> c . d) (b x)

Now let's replace the other .:

f b x = (\c d y -> c (d y)) (b x)

Now let's apply the argument:

f b x = \d y -> (b x) (d y)

Now let's move the parameters again:

f b x d y = (b x) (d y)

Done.

like image 54
sepp2k Avatar answered Oct 15 '22 04:10

sepp2k


You can also gradually append arguments to f:

f = ((.) . )
f x = (.) . x
f x y = ((.) . x) y
      = (.) (x y)
      = ((x y) . )
f x y z = (x y) . z
f x y z t = ((x y) . z) t
          = (x y) (z t)
          = x y (z t)
          = x y $ z t

The result reveals that x and z are actually (binary and unary, respectively) functions, so I'll use different identifiers:

f g x h y = g x (h y)
like image 41
fghzxm Avatar answered Oct 15 '22 05:10

fghzxm