ポイントフリーをポイントフルに変換


9

Haskellハッカーなので、私はポイントフルよりもポイントフリー表記を好みます。残念ながら、一部の人々はポイントフリー表記を読むのが難しいと感じており、私がポイントフルで書くと、正しい数の括弧を得るのが難しいと感じています。ポイントフリーで書かれたコードをポイントフル表記に変換するのを手伝ってください!

ポイントフリー表記では、ある関数の出力を別の関数にフィードするためにポイント(そう、本当に)を使用します。たとえば、succ数値を取得して1を加算する関数があり、これを行う代わりに、数値に3を加算する関数を作成したいとします。

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

あなたはこれを行うことができます:

succ.succ.succ

Pointfreeは単一のパラメーターを取る関数でのみ機能します(とにかくこの課題)、関数がそうではなくsuccadd2つの数値を取り、それらを加算する場合、引数が1つだけになるまで引数をフィードする必要があります。

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

最後に、関数は他の関数を引数として取ることができます:

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

入力と期待される出力

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

ルール

  • バランスが取れている限り、出力に必要以上のスペースまたは括弧が含まれる場合があります。
  • 作成する変数の名前が\xコードの他の場所ですでに使用されていないことを確認する必要はありません
  • 関数を作成するか完全なプログラムを作成するかはあなたの選択です
  • これはcodegolf、バイトで最短のコードが勝ちます!

あなたは鈍くて便利だと思うかもしれません、それは2つの表記法の間で変換します(しかし可能であればコードも分解します):https : //blunt.herokuapp.com


15
pointfree表記では、ポイントを使用して1つの関数の出力を別の関数に送ります。これは明らかに、pointfreeが無意味ではないことを証明する試みです
Luis Mendo

1
「Pointfreeは、単一のパラメーターを取る関数でのみ機能します」。それは真実ではない。(+).(*3)と同じです\x y->3*x+y
ダミアン

2
@Damienチャレンジをより身近なものにしようとしていました。フクロウのようなことをすることもできます:(.).(.)これは次のように変換されます\i b c f -> i (b c f)
BlackCap

2
したがって、Haskellの構文を知らない人のために明確にするために、最初に入力の括弧を照合し、各最上位の括弧で囲まれた式で再帰する必要があります。その後、各置き換える.とし(、先頭に追加\xし、対応する追加xし、多くとして)として必要とされていますか?それともそれよりも複雑ですか?
Peter Taylor

1
@Linus \ d->f(\k->f(f d k))ですが、このチャレンジではすべてのドットに2つの引数が与えられると想定できます
BlackCap

回答:


4

Haskell、163142133バイト

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

イデオーネでお試しください。

非ゴルフ:

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

ハスケル、402の 289バイト

かなり長いですが、うまくいくと思います。

(!)=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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.