erreur « variable de type Ambigu » lors de la définition personnalisée « lire » fonction
-
22-09-2019 - |
Question
Tout en essayant de compiler le code suivant, qui est la version améliorée de lecture construite sur readMay du package sûr.
readI :: (Typeable a, Read a) => String -> a
readI str = case readMay str of
Just x -> x
Nothing -> error ("Prelude.read failed, expected type: " ++
(show (typeOf > (undefined :: a))) ++
"String was: " ++ str)
Je reçois une erreur de GHC:
WavefrontSimple.hs: 54: 81:
variable de type `a Ambigu » dans la contrainte:
`Typable un '
résultant d'une utilisation de `TypeOf » src / WavefrontSimple.hs: 54: 81-103
fix probable: ajouter une signature de type qui fixe ces variables de type (s) `
Je ne comprends pas pourquoi. Ce qui devrait être fixé pour obtenir ce que je voulais dire?
EDIT: Ok, donc la solution à utiliser ScopedTypeVariables
et forall a
dans fonctionne la signature de type. Mais pourquoi ce qui suit produit une erreur très similaire à celui ci-dessus? Le compilateur doit déduire le type car il est asTypeOf :: a -> a -> a
utilisé.
readI :: (Typeable a, Read a) => String -> a
readI str = let xx = undefined in
case readMay str of
Just x -> x `asTypeOf` xx
Nothing -> error ("Prelude.read failed, expected type: "
++ (show (typeOf xx)) ++
"String was: " ++ str)
La solution
Ce dernier ne fonctionne pas parce que le type de xx
est le même que le type de undefined
- à savoir, « forall un a. ». Le fait que vous forcer xx à utiliser avec un type de béton avec l'opérateur asTypeOf ne veut pas dire qu'il est moins polymorphes partout ailleurs.
Autres conseils
Le a
dans undefined :: a
et readI :: (Typeable a, Read a) => String -> a
ne sont pas les mêmes type a
. Il est comme si vous avez écrit readI :: ... a; readI = ... (undefined :: b)
.
{-# LANGUAGE ScopedTypeVariables #-}
readI :: forall a. (Typeable a, Read a) => String -> a
...
Je ne sais pas pourquoi votre x `asTypeOf` xx
ne semble pas fonctionner. Cela fait, bien que:
readI :: (Typeable a, Read a) => String -> a
readI str = xx where
xx = case readMay str of
Just x -> x
Nothing -> error ("Prelude.read failed, expected type: "
++ (show (typeOf xx)) ++
"String was: " ++ str)
Je pense que vous avez besoin des variables de type scope.
{-# LANGUAGE ScopedTypeVariables #-}
readI :: forall a. (Typeable a, Read a) => String -> a
readI str = case readMay str of
Just x -> x
Nothing -> error ("Prelude.read failed, expected type: " ++
(show (typeOf > (undefined :: a))) ++
"String was: " ++ str)