¿Cómo doy tipos genéricos de expresiones en una cláusula "dónde"?
Frecuentes
Visto 395 veces
7
(por favor disculpe el ejemplo horriblemente artificial)
Lo que quiero hacer es especificar tipos en la cláusula where:
somemap :: (a -> b) -> [a] -> [b]
somemap f xs = ys
where
some = take 5 xs :: [a]
ys = map f some :: [b]
Pero esto provoca un error:
*Main> :load file.hs
[1 of 1] Compiling Main ( file.hs, interpreted )
fil.hs:15:18:
Couldn't match expected type `a1' against inferred type `a'
`a1' is a rigid type variable bound by
an expression type signature at file.hs:15:25
`a' is a rigid type variable bound by
the type signature for `somemap' at file.hs:12:12
Expected type: [a1]
Inferred type: [a]
In the second argument of `take', namely `xs'
In the expression: take 5 xs :: [a]
file.hs:16:13:
Couldn't match expected type `b1' against inferred type `b'
`b1' is a rigid type variable bound by
an expression type signature at file.hs:16:24
`b' is a rigid type variable bound by
the type signature for `somemap' at file.hs:12:17
In the first argument of `map', namely `f'
In the expression: map f some :: [b]
In the definition of `ys': ys = map f some :: [b]
Failed, modules loaded: none.
Mientras que si solo especifico tipos concretos, sustituyendo Int
por a
y Bool
por b
, no hay problema:
somemap :: (Int -> Bool) -> [Int] -> [Bool]
somemap f xs = ys
where
some = take 5 xs :: [Int]
ys = map f some :: [Bool]
Así que mi pregunta es la siguiente: ¿Cómo especifico tipos genéricos y restricciones de tipos en una cláusula where?
1 Respuestas
15
Dentro de la where
cláusula, las variables de tipo a
y b
se encuentran las Un nuevo tipo variables; Las variables de tipo no tienen alcance, por lo que cada firma de tipo tiene un nuevo suministro de ellas, como si estuvieran definidas en el nivel superior.
Si enciendes el ScopedTypeVariables
extensión (poner {-# LANGUAGE ScopedTypeVariables #-}
en la parte superior de su archivo), y cambie somemap
declaración de tipo a:
somemap :: forall a b. (a -> b) -> [a] -> [b]
entonces el where
definiciones de cláusulas que especificó funcionarán correctamente. creo que el forall
s solo se requieren para la compatibilidad con versiones anteriores, por lo que el código que reutiliza variables de tipo en where
las cláusulas para valores polimórficos no se rompen.
Si no quiere usar una extensión, la alternativa es definir funciones auxiliares feas para unificar los tipos, como asTypeOf
.
contestado el 03 de mayo de 12 a las 16:05
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas generics haskell types where-clause type-declaration or haz tu propia pregunta.
El código en stackoverflow.com/questions/7408911/… es un buen ejemplo de la confusión que puede surgir de tales "funciones auxiliares feas". - John L