Konvertieren Sie pointfree in pointful

9

Als Haskell-Hacker bevorzuge ich die punktfreie Notation gegenüber der sinnvollen. Leider fällt es einigen Leuten schwer, eine punktfreie Notation zu lesen, und ich finde es schwierig, die richtige Anzahl von Klammern zu erhalten, wenn ich in Punkt schreibe. Helfen Sie mir, in punktfreier Schreibweise geschriebenen Code in sinnvolle Notation umzuwandeln!

Über

In der punktfreien Notation verwenden wir Punkte (ja, wirklich), um die Ausgabe einer Funktion in eine andere einzuspeisen. Angenommen, Sie hatten eine Funktion succ, die eine Zahl nimmt und 1 hinzufügt, und Sie wollten eine Funktion erstellen, die einer Zahl 3 hinzufügt, anstatt dies zu tun:

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

Sie könnten dies tun:

succ.succ.succ

Pointfree funktioniert nur mit Funktionen , die jedoch nur einen Parameter übernehmen (in dieser Herausforderung sowieso), so dass , wenn unsere Aufgabe war es nicht , succsondern adddie 2 Zahlen nehmen und fügt sie zusammen, hätten wir es Argumente füttern , bis nur noch einer übrig ist:

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

Schließlich können Funktionen andere Funktionen als Argumente verwenden:

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))

Eingabe und erwartete Ausgabe

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)))

Regeln

  • Ihre Ausgabe enthält möglicherweise mehr Leerzeichen oder Klammern als erforderlich, sofern diese ausgeglichen sind
  • Sie müssen nicht sicherstellen, dass der Name der von Ihnen erstellten Variablen \xnicht bereits an einer anderen Stelle im Code verwendet wird
  • Sie haben die Wahl, ob Sie eine Funktion oder ein vollständiges Programm erstellen möchten
  • Dies ist codegolf, kürzester Code in Bytes gewinnen!

Möglicherweise ist stumpf nützlich. Es konvertiert zwischen den beiden Notationen (faktorisiert aber auch den Code, wenn möglich): https://blunt.herokuapp.com

BlackCap
quelle
15
In der punktfreien Notation verwenden wir Punkte, um die Ausgabe einer Funktion in eine andere einzuspeisen. Dies ist eindeutig ein Versuch zu beweisen, dass punktfrei nicht sinnlos ist
Luis Mendo
1
"Pointfree funktioniert nur mit Funktionen, die einen einzelnen Parameter annehmen". Das ist nicht wahr: (+).(*3)ist das gleiche wie\x y->3*x+y
Damien
2
@ Damien Ich habe versucht, die Herausforderung zugänglicher zu machen. Sie können auch Dinge wie die Eule tun: (.).(.)die konvertiert zu\i b c f -> i (b c f)
BlackCap
2
Aus Gründen der Klarheit für diejenigen, die die Syntax von Haskell nicht auswendig kennen: Wir sollten zuerst die Klammern in der Eingabe abgleichen und auf jeden Ausdruck in Klammern der obersten Ebene zurückgreifen. und dann jeweils .durch a ersetzen (, a voranstellen \xund ein entsprechendes xund so viele )wie nötig anhängen ? Oder ist es komplizierter?
Peter Taylor
1
@ Linus \ d->f(\k->f(f d k)), aber Sie können davon ausgehen, dass alle Punkte zwei Argumente in dieser Herausforderung
gefüttert werden

Antworten:

4

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

Probieren Sie es auf Ideone.

Ungolfed:

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++")"))
Laikoni
quelle
2

Haskell, 402 289 Bytes

Ziemlich lange, aber ich denke es funktioniert ..

(!)=elem
n%'('=n+1
n%')'=n-1
n%_=n
a?n=a!"."&&n<1
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
Damien
quelle