Avec -XTypeApplications
dans GHC 8.0, vous pouvez spécifier des types explicitement avec @
les arguments de fonction précédents. Quels types spécifie-t-il exactement, particulièrement quand plusieurs @
sont présentés?Comment utilisez-vous TypeApplications dans Haskell?
Répondre
Si vous regardez le type d'une fonction
elem :: (Foldable t, Eq a) => a -> t a -> Bool
nous voyons qu'il a deux variables polymorphes, t
et a
. Ces variables sont ce que les applications de type @
spécifient. Il semble que les variables introduites dans le contexte - où les contraintes de typeclass vont - affectent l'ordre, et donc le premier @
spécifie le t
, et le second le a
. Dans les fonctions sans variables de contexte
const :: a -> b -> a
l'ordre est plus évident, le a
est d'abord et b
est deuxième. Comme Cactus mentionné dans un commentaire ci-dessus, vous pouvez également utiliser des foralls explicites pour spécifier la commande vous-même. Maintenant, la première application de type
myConst :: forall b a. a -> b -> a
précisera le b
et le second le a
.
Vous pouvez rencontrer ce problème d'avoir besoin de spécifier les types en particulier si vous utilisez dans ce cas des chaînes surchargées ou des listes
elem c "abc...xyz" -- What string type is this?
elem c ['a' .. 'z'] -- What list constructor is this?
donc nous utilisons des applications de type explicites
elem @[] @Char c ['a' .. 'z']
nous ne avoir pour spécifier le @[]
et dire "ceci est un constructeur de type liste []
" parce que GHC infère Char
à partir des éléments de la liste, donc @Char
peut être omis ici. Si un argument polymorphe que GHC peut déduire arrive arrive en premier, vous pouvez tirer parti de -XPartialTypeSignatures
qui vous permet d'utiliser _
dans les signatures de type, y compris les signatures d'application de type, en disant à GHC d'en déduire que le type [partie du] les choses sont moins verbeuses.
f @_ @[]
Je pense que c'est une bonne idée d'utiliser 'ExplicitForAll' (ou' TypedScopeVariables' qui subsume il) si vous avez l'intention d'utiliser 'TypeApplications', puisque dans ce cas il n'y a pas d'ambiguïté: si vous avez par exemple 'const :: forall a b. a -> b -> a', alors le premier '@' -argument sera pour 'a', et le second pour' b'. – Cactus
'ScopedTypeVariables' – dfeuer