J'ai reçu la question suivante lors d'un test:
Écrivez une fonction
f
avec le type suivanta -> b -> (a -> b)
.a
etb
ne doit en aucun cas être lié, plus le code est court, mieux c'est.
Je suis venu avec f a b = \x -> snd ([a,x],b)
. Pouvez-vous trouver quelque chose de plus petit?
Actuellement, le gagnant est: f _=(.f).const
code-golf
functional-programming
haskell
Radu Stoenescu
la source
la source
f = const const
.f _ b _ = b
, mais, étant donné la solution de la question, je soupçonne qu'un type plus général n'est pas autorisé.f = id
?f = f
c'est une solution, donc je suppose que les conditions sur le type sont très importantes!Réponses:
Votre exemple peut être réduit en supprimant la fonction anonyme sur le côté droit:
Cela fonctionne parce que le type
a -> b -> a -> b
est équivalent àa -> b -> (a -> b)
Haskell.la source
f a b x = snd (f x,b)
La fonction
f _=(.f).const
est en fait d'un type plus général quef :: a -> b -> (a -> b)
, à savoirf :: a -> b -> (c -> b)
. Si aucune signature de type n'est donnée, le système d'inférence de type déduit un type def :: a -> b -> (a -> b)
, mais si vous incluez la signature de typef :: a -> b -> (c -> b)
avec la même définition exacte, Haskell la compilera sans problème et signalera des types cohérents pour les applications partielles de f. Il y a probablement une raison profonde pour laquelle le système d'inférence de type est plus strict que le système de vérification de type dans ce cas, mais je ne comprends pas assez la théorie des catégories pour trouver une raison pour laquelle cela devrait être le cas. Si vous n'êtes pas convaincu, vous êtes invités à l'essayer vous-même.la source
f a b = f a a
. il en déduit être de typea -> a -> b
bien qu'il soit conforme au typea -> b -> c
. c'est parce que sif
on ne lui donne pas de type, il ne peut s'utiliser que de façon monomorphe.Étant donné
ScopedTypeVariables
, je suis venu avec ceci:Si vous rétrécissez à la fois ma fonction et la vôtre, la mienne est un poil plus court:
Bien sûr, vous n'êtes probablement pas autorisé à vous fier à
ScopedTypeVariables
: P.la source
f _=(.f).const
(en raison de Sassa NF ). Qui n'a pas non plus besoinScopedTypeVariables
.