`Ord a =>` o `num a =>`
-
27-10-2019 - |
Pregunta
Tengo las siguientes funciones:
which (x:xs) = worker x xs
worker x [] = x
worker x (y:ys)
| x > y = worker y ys
| otherwise = worker x ys
y me pregunto cómo debo definir los tipos de firmas de estas funciones anteriores which
y worker
?
Por ejemplo, ¿cuál de las siguientes maneras sería mejor como un Tipo de firma para trabajador?
worker :: Num a => a -> [a] -> a
,
o
worker :: Ord a => a -> [a] -> a
?
Estoy realmente confundido y no entiendo cuáles deben elegir estos tres. Agradecería tus pensamientos. Gracias.
Solución
Si define la función sin una firma de tipo explícito, Haskell inferirá la más general. Si no está seguro, esta es la forma más fácil de descubrir cómo se lee su definición; Luego puede copiarlo en su código fuente. Un error común es escribir incorrectamente una función y luego obtener un error de tipo confuso en otro lugar.
De todos modos, puedes obtener información sobre el Num
clase escribiendo :i Num
en GHCI, o leyendo la documentación. los Num
La clase te da +
, *
, -
, negate
, abs
, signum
, fromInteger
, así como cada función de Eq
y Show
. Darse cuenta de <
y >
¡No hay! Requiriendo valores de Num
e intentar compararlos, de hecho, producirá un error de tipo, no se puede comparar todo tipo de número.
Entonces debería ser Ord a => ...
, como Num a => ...
Produciría un error de tipo si lo probaste.
Otros consejos
Si piensas en lo que hacen tus funciones, verás eso which xs
Devuelve el valor mínimo en xs
. ¿Qué puede tener un valor mínimo? Una lista de algo Ord
¡ERABLE!
Pregúntale a GHCI y mira qué dice. Acabo de copiar su código como está en un archivo y lo cargué en GHCI. Entonces usé :t
que es un comando GHCI especial para determinar el tipo de algo.
ghci> :t which
which :: (Ord t) => [t] -> t
ghci> :t worker
worker :: (Ord a) => a -> [a] -> a
La inferencia de tipo de Haskell es bastante inteligente en la mayoría de los casos; Aprenda a confiar en él. Otras respuestas cubren suficientemente por qué Ord
debe usarse en este caso; Solo quería asegurarme de que GHCI se mencionara claramente como una técnica para determinar el tipo de algo.
Siempre iría con la restricción de tipo Ord. Es el más general, por lo que se puede reutilizar con más frecuencia.
No hay ventaja en el uso de NUM sobre Ord.
INT puede tener una pequeña ventaja, ya que no es polimórfica y no requeriría una búsqueda de diccionario. Solicitaría Ord y usaría el Pragma especializado si fuera necesario para el rendimiento.
Editar: alteró mi respuesta después de los comentarios.
Depende de lo que quieras poder comparar. Si quieres poder comparar Double
, Float
, Int
, Integer
y Char
Luego usa Ord
. Si solo quieres poder comparar Int
Entonces solo usa Int
.
Si tiene otro problema como este, solo mire las instancias de la clase de tipo para decir qué tipos desea poder usar en la función.