Question

Après avoir joué avec haskell un peu je suis tombé sur cette fonction:

Prelude Data.Maclaurin> :t ((+) . ($) . (+))
((+) . ($) . (+)) :: (Num a) => a -> (a -> a) -> a -> a

(Data.Maclaurin est exportée par le vecteur de l'espace de l'emballage.) Ainsi, il faut un Num, une fonction, un autre Num et retourne finalement un Nb. Quelle magie fait les travaux suivants?

Prelude Data.Maclaurin> ((+) . ($) . (+)) 1 2 3
6

2 est évidemment pas une fonction (a-> a) ou ne me manque sur quelque chose?

Était-ce utile?

La solution

Le le module de Data.NumInstances du même paquet définit une instance de Num pour les fonctions qui renvoient les numéros:

instance Num b => Num (a->b) where
  (+)         = liftA2 (+)
  (*)         = liftA2 (*)
  fromInteger = pure . fromInteger
  ...

Dans Haskell un littéral entier comme 2 est générique afin qu'il puisse représenter un numéro pour toute instance de Num:

Prelude> :t 2
2 :: (Num t) => t

Pour convertir un nombre réel du type requis dans un contexte spécifique, fromInteger de la classe Num est appelée.

Etant donné que le module auxiliaire mentionné ci-dessus définit une instance de Num pour les fonctions, 2 peuvent maintenant être converties en une fonction avec la méthode fromInteger il spécifiée. Ainsi, les appels ghci fromInteger 2 pour obtenir la fonction requise comme second paramètre de la construction dans la question. L'expression tout se passe alors d'évaluer à 6.

Autres conseils

Vous avez de bonnes raisons d'être confondu. Utilisation du module de Data.NumInstances en GHC (qui est chargé par Data.Maclaurin), il est possible de contraindre un Num à une fonction constante.

Prelude Data.NumInstances> :t (2 :: (Num a) => a -> a)
(2 :: (Num a) => a -> a) :: (Num a) => a -> a
Prelude Data.NumInstances> (2 :: (Num a) => a -> a) 0          
2
Prelude Data.NumInstances> (2 :: (Num a) => a -> a) 1000
2

L'évaluation de l'expression est, en substance,

((+) . ($) . (+)) 1 2 3 = ((+) . ($) . (1+)) 2 3
                        = ((+) (1+)) 2 3
                        -- (+) is defined for functions that return a Num
                        = ((+) (1+) (\_ -> 2)) 3  
                        = ((+2) . (1+)) 3
                        = 6
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top