Jaki jest najkrótszy sposób na wyrażenie funkcji
f(a,b)(c,d)=(a+c,b+d)
w notacji bez punktów?
pointfree.io daje nam
uncurry (flip flip snd . (ap .) . flip flip fst . ((.) .) . (. (+)) . flip . (((.) . (,)) .) . (+))
które przy odrobinie pracy można skrócić
uncurry$(`flip`snd).((<*>).).(`flip`fst).((.).).(.(+)).flip.(((.).(,)).).(+)
dla 76 bajtów. Ale wciąż wydaje się to naprawdę długie i skomplikowane jak na tak proste zadanie. Czy jest jakiś sposób, aby wyrazić dodawanie parami jako krótszą funkcję bez punktów?
Aby wyjaśnić, co mam na myśli przez określenie „bez punktów”, deklaracja funkcji bez punktów obejmuje przejęcie istniejących funkcji i operatorów i zastosowanie ich względem siebie w taki sposób, aby utworzyć żądaną funkcję. Backticks, nawiasy i wartości literalne ( []
, 0
, [1..3]
, itd) są dozwolone, ale słowa kluczowe, jak where
i let
nie. To znaczy:
Nie możesz przypisywać żadnych zmiennych / funkcji
Nie możesz używać lambdas
Nie możesz importować
(+)***(+)
.(+)<$>([1],2)<*>([3],4)
daje([1,3],6)
.Odpowiedzi:
44 bajty
Mam to od
\x y -> (fst x + fst y, snd x + snd y)
Wypróbuj online!
źródło
44 bajty
-8 bajtów dzięki Ørjan Johansen. -3 bajty dzięki Bruce Forte.
Wypróbuj online!
Przetłumaczyć na:
67 bajtów
-8 bajtów dzięki Ørjan Johansen. -1 bajt dzięki Bruce Forte.
Jeśli wymagane jest wyjście krotki:
Wypróbuj online!
Tak, ręcznie to robię, nie produkując dojrzałych owoców. Ale cieszę się z
[a] → (a, a)
nawrócenia.Teraz jeśli jest krótka funkcja z
m (a → b) → a → m b
.źródło
mapM id[fst,snd]
jest krótszy.mapM id
jest to gra w golfa , której prawdopodobnie szukaszsequence
.(<*>)
podpis, który jestm (a → b) → m a → m b
. Tak blisko ...Control.Lens.??
, które w pewnym momencie mogły zostać zaproponowane do włączenia do bazy.(.mapM id[fst,snd])
jaklet r=(.mapM id[fst,snd]) in r(r.zipWith(+))
, ale nie byłem w stanie uzyskać typechecker przyjąć wersję pointfree.54 bajty
Szczerze wątpię, że pokonamy 44 bajtowe rozwiązanie H.PWiz, ale nikt nie używał faktu, że
(,)
implementuje klasę typówFunctor
, więc oto kolejna interesująca, która nie jest taka zła:Wypróbuj online!
Wyjaśnienie
Implementacja klasy typu
Functor
dla 2- krotek jest bardzo podobna doEither
(z base-4.10.1.0 ):Dla tego wyzwania oznacza to, że następująca funkcja dodaje drugie elementy, zachowując pierwszy element drugiego argumentu:
Gdybyśmy tylko mieli małego pomocnika
helpPlz = \a b -> (fst a+fst b,snd b)
, moglibyśmy to(helpPlz<*>).flip(fmap.(+).snd)
zrobić. Na szczęście mamy narzędzie,pointfree
które daje nam:Po ponownym podłączeniu tej funkcji dochodzimy do powyższego rozwiązania (zwróć uwagę na to,
(<*>) = ap
co jest w bazie ).źródło
60 bajtów
Nie widzę
uncurry
tu żadnej miłości, więc pomyślałem, że wpadnę i to naprawię.Myślałem, ze wszystkie wymienione
fst
isnd
, że rozpakowaniu argumentyuncurry
mogłyby uzyskując pewne rezultaty. Najwyraźniej nie było tak owocne, jak się spodziewałem.źródło
uncurry
jest taki pełny. :( Ale możesz zastąpić nawiasy najbardziej zewnętrzne$
.