Pointfree'yi mantıklıya dönüştür


9

Haskell korsanı olarak anlamsız gösterimi tercih ederim. Ne yazık ki bazı insanlar anlamsız gösterimi okumakta zorlanıyorlar ve anlamlı yazarken doğru sayıda parantez almakta zorlanıyorum. Pointfree ile yazılmış kodu anlamlı gösterime dönüştürmeme yardım et!

hakkında

Noktasız gösterimde, bir işlevin çıktısını diğerine beslemek için noktaları (evet, gerçekten) kullanırız. Diyelim ki, succbir sayı alan ve ona 1 ekleyen bir işleviniz varsa ve bunu yapmak yerine bir sayıya 3 ekleyen bir işlev yapmak istiyorsanız:

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

bunu yapabilirsin:

succ.succ.succ

Pointfree sadece işlev değildi eğer öyleyse, (zaten bu meydan okumada) ancak tek bir parametresi alması fonksiyonları ile çalışır succziyade add2 sayı alıp, bunları toplar, hangi sadece bir sol kalmayıncaya kadar o argümanları beslemek gerekir:

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

Son olarak, işlevler diğer işlevleri bağımsız değişken olarak alabilir:

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

Girdi ve beklenen çıktı

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

kurallar

  • Çıktınızda, dengeli olduğu sürece gerekenden daha fazla alan veya parantez olabilir
  • Oluşturduğunuz değişkenin adının \xkodda başka bir yerde kullanılmadığından emin olmanız gerekmez
  • Bir işlev veya tam bir program oluşturmak sizin seçiminizdir
  • Bu codegolf, bayttaki en kısa kod kazanır!

Künt yararlı olabilir, iki gösterim arasında dönüşür (ancak mümkün olduğunda kodu çarpanlarına ayırır): https://blunt.herokuapp.com


15
Pointfree biz başka bir bir işlevin çıktısını beslemek için noktaları kullanın notasyonu açıkça pointfree kanıtlamak için bir girişim olduğunu bu anlamsız değildir
Luis Mendo

1
"Pointfree sadece tek bir parametre alan fonksiyonlarla çalışır". Bu doğru değil: (+).(*3)aynı\x y->3*x+y
Damien

2
@Damien Meydan okumayı daha erişilebilir hale getirmeye çalışıyordum. Ayrıca baykuş gibi şeyler de yapabilirsiniz: (.).(.)dönüştürmek\i b c f -> i (b c f)
BlackCap

2
Yani Haskell'in sözdizimini ezbere bilmeyenlere açıklık getirmek için: önce her bir üst düzey parantez ifadesinde girdi ve geri almadaki parantezleri eşleştirmeliyiz; ve her birini a .ile değiştirin (, a'nın başına \xekleyin ve karşılık gelen xve gerektiği kadar ekleyin )? Yoksa bundan daha mı karmaşık?
Peter Taylor

1
@Linus \ d->f(\k->f(f d k)), ancak bu meydan okumada tüm noktaların iki argümanla beslendiğini varsayabilirsiniz
BlackCap

Yanıtlar:


4

Haskell, 163142133 bayt

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

Ideone üzerinde deneyin.

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'in 402 289 bayt

Oldukça uzun, ama bence işe yarıyor ..

(!)=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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.