Question

Je possède les fonctions suivantes:

which (x:xs) = worker x xs
worker x [] = x
worker x (y:ys)
    | x > y      = worker y ys
    | otherwise  = worker x ys

et je me demande comment je définir les types de signatures de ces fonctions ci-dessus which et worker?

Par exemple, qui des façons suivantes seraient mieux une signature type pour les travailleurs?

worker :: Num a => a -> [a] -> a,

ou

worker :: Ord a => a -> [a] -> a?

Je suis vraiment confus et ne reçoivent pas que ces trois je devrais choisir. Je vous remercie de vos pensées. Merci.

Était-ce utile?

La solution

Si vous définissez la fonction sans une signature de type explicite, Haskell inférera le plus général. Si vous ne savez pas, ce sera lu est la meilleure façon de comprendre comment votre définition; vous pouvez le copier dans votre code source. Une erreur commune est en train de taper correctement une fonction et obtenir une erreur de type confusion ailleurs.

Quoi qu'il en soit, vous pouvez obtenir des informations sur la classe Num en tapant :i Num dans ghci, ou en lisant la documentation. La classe Num vous donne +, *, -, negate, abs, signum, fromInteger, ainsi que toutes les fonctions de Eq et Show. Notez que < et > ne sont pas là! Exiger des valeurs de Num et essayer de les comparer produiront en fait une erreur de type -. Pas tous les types de numéro peut être comparé

Il doit donc être Ord a => ..., comme Num a => ... produirait une erreur de type si vous essayé.

Autres conseils

Si vous pensez à ce que vos fonctions font, vous verrez que which xs retourne la valeur minimale dans xs. Qu'est-ce que peut avoir une valeur minimale? Une liste des Orderable quelque chose!

Demandez ghci et de voir ce qu'il dit. Je collais copie juste votre code tout comme dans un fichier et chargé dans ghci. Ensuite, je :t qui est une commande spéciale de ghci pour déterminer le type de quelque chose.

ghci> :t which
which :: (Ord t) => [t] -> t
ghci> :t worker
worker :: (Ord a) => a -> [a] -> a

inférence de type de Haskell est assez intelligent dans la plupart des cas; apprendre à lui faire confiance. D'autres réponses couvrent suffisamment pourquoi Ord doit être utilisé dans ce cas; Je voulais juste vous assurer ghci a été clairement mentionné comme une technique pour déterminer le type de quelque chose.

Je serais toujours aller avec la contrainte de type Ord. Il est le plus général, il peut donc être plus souvent réutilisé.

Il n'y a aucun avantage à utiliser Num sur Ord.

Int peut avoir un petit avantage car il est pas polymorphes et ne nécessiterait pas une recherche dans le dictionnaire. Je Stil utiliser Ord et utiliser le pragma specialize si je devais la performance.

Modifier. Altered ma réponse après les commentaires

Cela dépend de ce que vous voulez être en mesure de comparer. Si vous voulez être en mesure de comparer Double, Float, Int, Integer et Char puis utilisez Ord. Si vous voulez seulement être en mesure de comparer Int puis il suffit d'utiliser Int.

Si vous avez un autre problème comme celui-ci, il suffit de regarder les instances de la classe de type pour dire quels types vous voulez être en mesure d'utiliser dans la fonction.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top