ポイントフリーでのタプル追加


16

関数を表現できる最短の方法は何ですか

f(a,b)(c,d)=(a+c,b+d)

ポイントフリー表記で?

pointfree.ioは私たちに与えます

uncurry (flip flip snd . (ap .) . flip flip fst . ((.) .) . (. (+)) . flip . (((.) . (,)) .) . (+))

少しの作業で短縮できます

uncurry$(`flip`snd).((<*>).).(`flip`fst).((.).).(.(+)).flip.(((.).(,)).).(+)

76バイト。しかし、これは、そのような単純なタスクにとっては依然として非常に長く複雑です。ペアワイズ加算をより短いポイントフリー関数として表現する方法はありますか?

関数のポイントフリー宣言の意味を明確にするために、関数のポイントフリー宣言には、既存の関数と演算子を使用し、目的の関数が作成されるようにそれらを相互に適用することが含まれます。バッククォート、括弧やリテラル値([]0[1..3]、など)が許可されますが、キーワードは次のようにしているwhereletはありません。これの意味は:

  • 変数/関数を割り当てることはできません

  • ラムダは使用できません

  • インポートできません

これは、CMCであったときの同じ質問です


9
実際にポイントがいっぱいなのに、なぜ「ポイントフリー」と呼ばれるのか理解できませんでした。:P
ミスターXcoder


5
それは私たちが輸入する許可されていない残念だ最高のHaskellのパッケージ、または他の解決策がちょうどだろうが(+)***(+)
シルヴィオマヨロ

2
アイデア:(+)<$>([1],2)<*>([3],4)与え([1,3],6)ます。
xnor

2
私はxnorのヒントを利用して素晴らしいソリューションを作成しようといくつかの時間を費やしました...しかし、私はこのゴミになってしまいました。私は時々してみてくださいなぜ私もわからない...
totallyhuman

回答:



8

44バイト

ØrjanJohansenのおかげで-8バイト。ブルース・フォルテのおかげで-3バイト。

(.).flip(.)<*>(zipWith(+).)$mapM id[fst,snd]

オンラインでお試しください!

翻訳先:

f t1 t2 = zipWith (+) (mapM id [fst, snd] $ t1) (mapM id [fst, snd] $ t2)

67バイト

ØrjanJohansenのおかげで-8バイト。ブルース・フォルテのおかげで-1バイト。

タプル出力が必要な場合:

(((,).head<*>last).).((.).flip(.)<*>(zipWith(+).)$mapM id[fst,snd])

オンラインでお試しください!

うん、私はそれを手作業で行っても、熟した果物を生産しません。しかし、私は[a] → (a, a)回心に満足しています。

listToPair  [a]  (a, a)
listToPair = (,) . head <*> last
-- listToPair [a, b] = (a, b)

短い関数があった場合m (a → b) → a → m b


3
あなたにそれを破るのが嫌いですが、mapM id[fst,snd]短いです。
Ørjanヨハンセン

悲しいことに、mapM idあるgolfed、あなたはおそらく探している機能のバージョンsequence
Ørjanヨハンセン

ええ、それは本当です。私はただ(<*>)の署名を見ているだけですm (a → b) → m a → m b。だから、近い...
totallyhuman

1
またControl.Lens.??、ある時点でベースに含めることが提案されている可能性があります。
Ørjanヨハンセン

(.mapM id[fst,snd])ようlet r=(.mapM id[fst,snd]) in r(r.zipWith(+))に繰り返されたものを抽出したいのですが、タイプチェッカーでポイントフリーバージョンを受け入れることができませんでした。
XNOR

4

54バイト

@ H.PWizの44バイトのソリューションを打ち負かすことは正直に疑いますが(,)、型クラスを実装するという事実を使用しているFunctor人はいませんでした。

((<*>snd).((,).).(.fst).(+).fst<*>).flip(fmap.(+).snd)

オンラインでお試しください!

説明

型クラスの実装Functorのための2つのタプルはのものと非常に類似しているEither(からベース4.10.1.0)。

instance Functor ((,) a) where
    fmap f (x,y) = (x, f y)

instance Functor (Either a) where
    fmap _ (Left x) = Left x
    fmap f (Right y) = Right (f y)

これがこの課題に対して意味することは、次の関数が2番目の引数の最初の要素を保持しながら2番目の要素を追加することです。

λ f = fmap.(+).snd :: Num a => (a, a) -> (a, a) -> (a, a)
λ f (1,-2) (3,-4)
(3,-6)

ですから、もしhelpPlz = \a b -> (fst a+fst b,snd b)私たちにできる小さなヘルパーがあれば、それはできますし(helpPlz<*>).flip(fmap.(+).snd)、行われるでしょう。幸いなことに、次のようなツールがpointfreeあります。

helpPlz = (`ap` snd) . ((,) .) . (. fst) . (+) . fst

そのため、単純にその関数をプラグインするだけで、上記のソリューションに到達します((<*>) = apこれはbaseにあることに注意してください)。


4

60バイト

私はuncurryここで愛を見ていないので、私はそれをポップして修正するだろうと思った。

uncurry$(uncurry.).flip(.)(flip(.).(+)).(flip(.).((,).).(+))

私はすべてで、思ったfstsndして引数を開梱すること、uncurryいくつかの結果をもたらすかもしれません。明らかに、私が期待していたほど実りがありませんでした。


2
uncurryとても冗長です。:(ただし、最も外側の括弧を$。に置き換えることができます。
ØrjanJohansen

ええ、それは残念ながらHaskellの多くの関数名の問題です。ゴルフには長すぎます。しかし、1文字の節約に感謝します!
シルヴィオマヨロ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.