Being a Haskell hacker, I prefer pointfree notation over pointful. Unfortunately some people find pointfree notation hard to read, and I find it hard to get the correct number of parentheses when I write in pointful. Help me convert code written in pointfree to pointful notation!


In pointfree notation we use points (yes, really) to feed the output of one function into another. Say, if you had a function succ that takes a number and adds 1 to it, and you wanted to make a function that adds 3 to a number, instead of doing this:

\x -> succ(succ(succ(x)))

you could do this:


Pointfree only works with functions that take a single parameter however (in this challenge anyway), so if our function wasn't succ but rather add which take 2 numbers and adds them together, we would have to feed it arguments until there is only one left:

pointful:  \x -> add 1(add 1(add 1 x)) 
pointfree: add 1 . add 1 . add 1

Lastly, functions may take other functions as arguments:

Pointfree: map (f a . f b) . id
Pointful:  \x -> map (\x -> f a (f b x)) (id x)

Javascript equivalent: x => map (x => f(a,f(b,x)), id(x))

Input and expected output

f . f . f
\x -> f (f (f x))

f a . f b . f c
\x -> f a (f b (f c x))

f (f a . f b) . f c
\x -> f (\x -> f a (f b x)) (f c x)

a b c . d e . f g h i . j k l . m
\x -> a b c (d e (f g h i (j k l (m x))))

a.b(c.d)e.f g(h)(i j.k).l(m(n.o).p)
\x->a(b(\y->c(d y))e(f g h(\z->i j(k z))(l(\q->m(\w->n(o w))(p q))x)))


  • Your output may have more spaces or parentheses than required, as long as they are balanced
  • You don't have to make sure that the name of the variable you create \x isn't already used somewhere else in the code
  • It is your choice whether to create a function or a full program
  • This is codegolf, shortest code in bytes win!

You might find blunt useful, it converts between the two notations (but also factorizes the code when possible): https://blunt.herokuapp.com

  • 17
    \$\begingroup\$ In pointfree notation we use points to feed the output of one function into another That's clearly an attempt to prove that pointfree is not pointless \$\endgroup\$
    – Luis Mendo
    Sep 29, 2016 at 9:22
  • 1
    \$\begingroup\$ "Pointfree only works with functions that take a single parameter". That's not true: (+).(*3) is the same as \x y->3*x+y \$\endgroup\$
    – Damien
    Sep 29, 2016 at 9:33
  • 2
    \$\begingroup\$ @Damien I was trying to make the challenge more accessible. You can also do things like the owl: (.).(.) which converts to \i b c f -> i (b c f) \$\endgroup\$
    – BlackCap
    Sep 29, 2016 at 9:37
  • 2
    \$\begingroup\$ So for clarity for those who don't know the syntax of Haskell by heart: we should first match parentheses in the input and recurse on each top-level parenthesised expression; and then replace each . with a (, prepend a \x and append a corresponding x and as many ) as are required? Or is it more complicated than that? \$\endgroup\$ Sep 29, 2016 at 11:01
  • 1
    \$\begingroup\$ @Linus \ d->f(\k->f(f d k)), but you can assume that all the dots are fed two arguments in this challenge \$\endgroup\$
    – BlackCap
    Oct 1, 2016 at 11:35

2 Answers 2


Haskell, 163 142 133 bytes

p(x:r)|[a,b]<-p r=case[x]of"("->["(\\x->"++a++p b!!0,""];"."->['(':a++")",b];")"->[" x)",r];_->[x:a,b]
p r=[r,r]
f s=p('(':s++")")!!0

Try it on Ideone.


p('(':r)|(a,b)<-p r = ("(\\x->"++a++(fst(p b)),"")
p('.':r)|(a,b)<-p r = ('(':a++")",              b)
p(')':r)            = (" x)",                   r)
p(x  :r)|(a,b)<-p r = (x:a,                     b)
p _                 = ("",                     "")

f s=fst(p('(':s++")"))

Haskell, 402 289 bytes

Quite long, but I think it works..

a#n=a!" ("&&n<1||a!")"&&n<2
q a='(':a++")"
p s o n[]=[s]
p s o n(a:b)|o a n=[t|t@(q:r)<-s:p""o(n%a)b]|0<1=p(s++[a])o(n%a)b
k=foldr((++).(++" ").f)"".p""(#)0
f t|not$any(!"(. ")t=t|l@(x:r)<-p""(?)0t=q$"\\x->"++foldr((.q).(++).k)"x"l|0<1=k t

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.