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.

¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top