Pointfree'de grup ekleme


16

İşlevi ifade etmenin en kısa yolu nedir

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

işaretsiz gösterimde?

pointfree.io bize verir

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

biraz çalışma ile kısaltılabilir

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

76 bayt için. Ancak bu , böyle basit bir görev için hala çok uzun ve karmaşık görünüyor . Daha kısa bir noktadan bağımsız işlev olarak ikili eklemeyi ifade etmenin bir yolu var mı?

Noktadan arındırmakla ne demek istediğimi açıklığa kavuşturmak için, bir fonksiyonun noktasız bir beyanı, mevcut fonksiyonları ve operatörleri alıp bunları istenen fonksiyon yaratılacak şekilde birbirine uygulamayı içerir. Backticks, parantezler ve edebi değerleri ( [], 0, [1..3]vb) izin fakat gibi anahtar kelimeleri olduğunu whereve letdeğillerdir. Bu şu anlama gelir:

  • Herhangi bir değişken / işlev atayamazsınız

  • Lambdas kullanamazsınız

  • İçe aktaramazsınız

CMC olduğu zaman da aynı soru


9
Ben “nokta- denir neden hiç anlamadım özgür aslında olduğunda” tam puan. : P
Bay Xcoder


5
En iyi Haskell paketini ithal etmemize izin verilmez , aksi takdirde çözüm olur (+)***(+).
Silvio Mayolo

2
Bir fikir: (+)<$>([1],2)<*>([3],4)verir ([1,3],6).
xnor

2
Xnor'ın ipucunu kullanarak ince bir çözüm üretmeye çalışarak biraz zaman geçirdim ... ama bu çöple sonuçlandım . Neden bazen denediğimi bile bilmiyorum ...
totalhuman

Yanıtlar:



8

44 bayt

Ørjan Johansen sayesinde -8 bayt. Bruce Forte sayesinde -3 bayt.

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

Çevrimiçi deneyin!

Çevirir:

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

67 bayt

Ørjan Johansen sayesinde -8 bayt. Bruce Forte sayesinde -1 bayt.

Grup çıkışı gerekiyorsa:

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

Çevrimiçi deneyin!

Evet, elle yaptığımda olgun meyve üretmiyorum. Ama [a] → (a, a)dönüşümden memnunum .

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

Şimdi ile kısa bir fonksiyon olsaydı m (a → b) → a → m b.


3
Size kırmaktan nefret ediyorum, ama mapM id[fst,snd]daha kısadır.
Ørjan Johansen

Ne yazık ki, mapM idbir golfed muhtemelen aradığınız fonksiyonun versiyonu sequence.
Ørjan Johansen

Evet doğru. Sadece (<*>)imzasına bakıyorum m (a → b) → m a → m b. Çok yakın ...
totallyhuman

1
Ayrıca Control.Lens.??, bir noktada üsse dahil edilmek üzere önerilenler de olabilir .
Ørjan Johansen

Tekrarlanan (.mapM id[fst,snd])gibi ayıklamak istiyorum let r=(.mapM id[fst,snd]) in r(r.zipWith(+)), ancak daktiloyu anlamsız bir sürümü kabul edemedim.
xnor

4

54 bayt

Dürüst olmak gerekirse, @ H.PWiz'in 44 bayt çözümünü yeneceğimizden şüpheliyim, ancak kimse (,)tip sınıfını uygulayan gerçeği kullanmıyordu Functor, bu yüzden çok kötü olmayan bir başka ilginç olan:

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

Çevrimiçi deneyin!

açıklama

Tip sınıfın uygulanması Functoriçin 2 -Toples aşağıdakilere çok benzer Either( taban-4.10.1.0'dan ):

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)

Bu sorun için bunun anlamı, aşağıdaki işlevin ikinci argümanın ilk öğesini korurken ikinci elemanları eklemesidir:

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

Yani sadece küçük bir yardımcıya sahip helpPlz = \a b -> (fst a+fst b,snd b)olsaydık yapabilirdik (helpPlz<*>).flip(fmap.(+).snd)ve yapardık . Neyse ki araca sahibizpointfree bize veren var:

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

Bu işlevi tekrar takarak yukarıdaki çözüme ulaşıyoruz ( (<*>) = aphangisinin temelde olduğuna dikkat edin ).


4

60 bayt

uncurryBurada hiç aşk görmüyorum , bu yüzden içeri girip onu tamir edeceğimi düşündüm.

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

Tüm fstve sndile birlikte, argümanları uncurryaçmanın bazı sonuçlar doğurabileceğini düşündüm . Açıkçası, umduğum kadar verimli değildi.


2
uncurryçok ayrıntılı. :( Ama en dıştaki parantezleri $.
Ørjan Johansen

Evet, ve bu ne yazık ki Haskell'de birçok işlev adıyla ilgili bir sorun. Golf için çok uzun. Ancak 1 karakterlik tasarruf için teşekkürler!
Silvio Mayolo
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.