Quel est le moyen le plus court pour exprimer la fonction
f(a,b)(c,d)=(a+c,b+d)
en notation sans point?
pointfree.io nous donne
uncurry (flip flip snd . (ap .) . flip flip fst . ((.) .) . (. (+)) . flip . (((.) . (,)) .) . (+))
qui avec un peu de travail peut être raccourci
uncurry$(`flip`snd).((<*>).).(`flip`fst).((.).).(.(+)).flip.(((.).(,)).).(+)
pour 76 octets. Mais cela semble encore très long et complexe pour une tâche aussi simple. Existe-t-il un moyen d'exprimer l'addition par paire comme une fonction sans point plus courte?
Pour être clair par ce que j'entends par point-free, une déclaration point-free d'une fonction implique de prendre des fonctions et des opérateurs existants et de les appliquer les uns aux autres de telle sorte que la fonction souhaitée soit créée. Entre parenthèses, et les apostrophes inverses des valeurs littérales ( []
, 0
, [1..3]
, etc.) sont autorisés , mais des mots clés comme where
et let
ne sont pas. Ça signifie:
Vous ne pouvez attribuer aucune variable / fonction
Vous ne pouvez pas utiliser de lambdas
Vous ne pouvez pas importer
(+)***(+)
.(+)<$>([1],2)<*>([3],4)
donne([1,3],6)
.Réponses:
44 octets
J'ai obtenu ça de
\x y -> (fst x + fst y, snd x + snd y)
Essayez-le en ligne!
la source
44 octets
-8 octets grâce à Ørjan Johansen. -3 octets grâce à Bruce Forte.
Essayez-le en ligne!
Se traduit par:
67 octets
-8 octets grâce à Ørjan Johansen. -1 octet merci à Bruce Forte.
Si une sortie de tuple est requise:
Essayez-le en ligne!
Ouais, le fait manuellement ne produit pas de fruits mûrs. Mais je suis satisfait de la
[a] → (a, a)
conversion.Maintenant, s'il y avait une fonction courte avec
m (a → b) → a → m b
.la source
mapM id[fst,snd]
c'est plus court.mapM id
c'est la version golfée de la fonction que vous recherchez probablementsequence
.(<*>)
la signature dem (a → b) → m a → m b
. Si proche ...Control.Lens.??
, qui peut avoir été proposé pour inclusion dans la base à un moment donné.(.mapM id[fst,snd])
commelet r=(.mapM id[fst,snd]) in r(r.zipWith(+))
, mais je n'ai pas réussi à faire en sorte que le vérificateur de type accepte une version sans point.54 octets
Je doute sincèrement que nous allons battre la solution de 44 octets de @ H.PWiz, mais personne n'utilisait le fait qui
(,)
implémente la classe de typeFunctor
, alors voici une autre intéressante qui n'est pas trop mauvaise:Essayez-le en ligne!
Explication
L'implémentation de la classe de type
Functor
pour 2 -Tuples est très similaire à celle deEither
(à partir de la base-4.10.1.0 ):Ce que cela signifie pour ce défi, c'est que la fonction suivante ajoute les seconds éléments tout en conservant le premier élément du deuxième argument:
Donc, si seulement nous obtenions une petite aide,
helpPlz = \a b -> (fst a+fst b,snd b)
nous pourrions le faire(helpPlz<*>).flip(fmap.(+).snd)
et le serions. Heureusement, nous avons l'outilpointfree
qui nous donne:Donc, en rebranchant simplement cette fonction, nous arrivons à la solution ci-dessus (notez celle
(<*>) = ap
qui est dans la base ).la source
60 octets
Je ne vois aucun
uncurry
amour ici, alors je me suis dit que j'allais intervenir et réparer ça.J'ai pensé, avec tous les
fst
etsnd
, que déballer les arguments avecuncurry
pourrait donner des résultats. De toute évidence, ce n'était pas aussi fructueux que je l'avais espéré.la source
uncurry
est tellement verbeux. :( Mais vous pouvez remplacer les parenthèses les plus externes par$
.