Converti pointfree in pointful


9

Essendo un hacker di Haskell, preferisco la notazione senza senso piuttosto che puntuale. Sfortunatamente alcune persone trovano difficile leggere una notazione senza senso e trovo difficile ottenere il numero corretto di parentesi quando scrivo in modo puntuale. Aiutami a convertire il codice scritto in pointfree in notazione puntuale!

Di

Nella notazione senza punti usiamo i punti (sì, davvero) per alimentare l'output di una funzione in un'altra. Ad esempio, se hai una funzione succche accetta un numero e ne aggiunge 1, e volevi creare una funzione che aggiunge 3 a un numero, invece di farlo:

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

potresti farlo:

succ.succ.succ

Pointfree funziona solo con funzioni che accettano comunque un singolo parametro (in questa sfida comunque), quindi se la nostra funzione non lo fosse succma piuttosto addche prende 2 numeri e li somma insieme, dovremmo alimentare gli argomenti fino a quando ne rimane solo uno:

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

Infine, le funzioni possono assumere altre funzioni come argomenti:

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 e output attesi

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

Regole

  • L'output potrebbe avere più spazi o parentesi del necessario, purché siano bilanciati
  • Non devi assicurarti che il nome della variabile che crei \xnon sia già utilizzato da qualche altra parte nel codice
  • Puoi scegliere se creare una funzione o un programma completo
  • Questo è codegolf, il codice più corto in byte vince!

Potresti trovare utile contundente, converte tra le due notazioni (ma anche fattorizza il codice quando possibile): https://blunt.herokuapp.com


15
Nella notazione senza punti usiamo i punti per alimentare l'output di una funzione in un'altra Questo è chiaramente un tentativo di dimostrare che il punto privo di significato non ha senso
Luis Mendo,

1
"Pointfree funziona solo con funzioni che accettano un singolo parametro". Non è vero: (+).(*3)è lo stesso di\x y->3*x+y
Damien,

2
@Damien Stavo cercando di rendere la sfida più accessibile. Puoi anche fare cose come il gufo: (.).(.)che si converte in\i b c f -> i (b c f)
BlackCap

2
Quindi, per chiarezza per coloro che non conoscono a memoria la sintassi di Haskell: dovremmo prima abbinare le parentesi nell'input e ricorrere su ogni espressione tra parentesi di livello superiore; e quindi sostituire ciascuno .con a (, anteporre a \xe aggiungere un corrispondente xe quanti ne )sono necessari? O è più complicato di così?
Peter Taylor,

1
@Lino \ d->f(\k->f(f d k)), ma puoi supporre che tutti i punti siano alimentati da due argomenti in questa sfida
BlackCap

Risposte:


4

Haskell, 163 142 133 byte

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

Provalo su 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++")"))

2

Haskell, 402 289 byte

Abbastanza a lungo, ma penso che funzioni ..

(!)=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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.