Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write f in pointfree-style?

Say I have functions

g :: a -> b, h :: a -> c 

and

f :: b -> c -> d. 

Is it possible to write the function

 f' :: a -> a -> d 

given by

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

in point free style?.

One can write the function

f' a -> d, f' x = f (g x) (h x) 

in point free style by setting

f' = (f <$> g) <*> h  

but I couldn't figure out how to do the more general case.

like image 683
user3726947 Avatar asked Nov 28 '22 01:11

user3726947


2 Answers

We have:

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

and we wish to write k in point-free style.

The first argument passed to k is x. What do we need to do with x? Well, first we need to call g on it, and then f, and then do something fancy to apply this to (h y).

k = fancy . f . g

What is this fancy? Well:

k x y = (fancy . f . g) x y
      = fancy (f (g x)) y
      = f (g x) (h y)

So we desire fancy z y = z (h y). Eta-reducing, we get fancy z = z . h, or fancy = (. h).

k = (. h) . f . g

A more natural way to think about it might be

                             ┌───┐           ┌───┐
                        x ───│ g │─── g x ───│   │
                      /      └───┘           │   │
               (x, y)                        │ f │─── f (g x) (h y)
                      \      ┌───┐           │   │
                        y ───│ h │─── h y ───│   │
                             └───┘           └───┘

                      └──────────────────────────────┘
                                      k

Enter Control.Arrow:

k = curry ((g *** h) >>> uncurry f)
like image 145
Lynn Avatar answered Nov 29 '22 15:11

Lynn


Take a look at online converter

It converted

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

into

f' = (. h) . f . g

with the flow of transformations

f' = id (fix (const (flip ((.) . f . g) h))) 
f' = fix (const (flip ((.) . f . g) h)) 
f' = fix (const ((. h) . f . g)) 
f' = (. h) . f . g
like image 20
Nazarii Bardiuk Avatar answered Nov 29 '22 14:11

Nazarii Bardiuk