Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pointfree returning a tuple in Haskell

Can a pointfree function return a tuple? For instance, can the following be written in pointfree style (where f1, f2, and f3 have been defined):

(\t -> (f1 t, f2 t, f3 t))

In this case, my f1, f2, and f3 are compositions of quot, mod, *, and some integers.

(\f1,f2,f3 -> (\t -> (f1 t, f2 t, f3 t)))

is a more general case, and is equivalent to

(\f1,f2,f3,t -> (f1 t, f2 t, f3 t))

Named functions are OK, but my examples are anonymous. (Named examples would be as follows)

f x = (f1 x, f2 x, f3 x)
f f1 f2 f3 x = (f1 x, f2 x, f3 x)

EDIT: I'm just curious for fun, I'm not going to do this.

like image 694
Andrew Wonnacott Avatar asked Nov 29 '22 08:11

Andrew Wonnacott


1 Answers

You can write

(\t -> (f1 t, f2 t, f3 t))

pointfree, it's

liftM (,,) f1 `ap` f2 `ap` f3

with ap from Control.Monad and the Monad instance of (->) a from Control.Monad.Instances. A somewhat more readable form may be the Control.Applicative variant

(,,) <$> f1 <*> f2 <*> f3

You can then further point-free

(\f1 f2 f3 -> (\t -> (f1 t, f2 t, f3 t)))

As

  \f1 f2 f3 -> (,,) <$> f1 <*> f2 <*> f3
= \f1 f2 -> ((,,) <$> f1 <*> f2 <*>)
= \f1 f2 -> (<*>) ((,,) <$> f1 <*> f2)
= \f1 f2 -> ((<*>) . ((,,) <$> f1 <*>)) f2
= \f1 -> (<*>) . ((,,) <$> f1 <*>)
= \f1 -> (<*>) . (<*>) ((,,) <$> f1)
= \f1 -> (((<*>) .) . (<*>) . (<$>) (,,)) f1
= ((<*>) .) . (<*>) . (<$>) (,,)

but seriously, you shouldn't. Keep it readable, that means a bit of pointfreeing is good, but don't overdo it.

like image 200
Daniel Fischer Avatar answered Dec 05 '22 03:12

Daniel Fischer