Escriba tipos de firma para listas, etc.
-
28-10-2019 - |
Pregunta
¿Cómo definiría las siguientes firmas de tipo en inglés sencillo?
Ord a => ...
Eq a => ...
Num a => ...
¿Podría describir el significado de estos y dejarme saber cuáles son las diferencias (en términos de cómo le explicaría a otra persona)?
Gracias.
Solución
Todos estos son ejemplos de "restricciones de clase": limitan qué tipos se pueden usar en lugar de la variable de tipo que los sigue (a
en este caso), lo que requiere que pertenezca a un clase tipo. Ord
, Eq
y Num
son ejemplos de clases de tipo.
Ord a => ...
medioa
es un tipo que tiene una noción natural de orden asociada con él. Por ejemplo, los enteros se pueden organizar naturalmente de más pequeño a más grande. En términos matemáticos, existe un orden total ena
. Un ejemplo obvio que una función que requiere esta restricción essort :: Ord a => [a] -> [a]
; Lea esta firma diciendo quesort
Solo funciona en listas de cosas que se pueden poner en orden en relación entre sí.Eq a => ...
medioa
es un tipo cuyos miembros se pueden comparar entre sí para alguna noción de igualdad. En términos matemáticos, existe un relación de equivalencia ena
. Tenga en cuenta que esta es una superclase deOrd
, lo que significa cualquier cosa que tenga una noción de ordenamiento también debe tener una noción de equivalencia. Un ejemplo de una función que requiere esta restricción eselem :: Eq a => a -> [a] -> Bool
(que determina si una lista contiene un elemento dado); Lea esta firma diciendo queelem
Solo funciona en listas de cosas que se pueden comparar entre sí para la igualdad. Si piensas en cómo escribiríaselem
tú mismo, eso debería tener sentido.Num a => ...
medioa
es un tipo numérico, lo que significa que admite algunas operaciones aritméticas básicas:+
,*
,-
,abs
. Creo que esto es más o menos similar a la noción matemática de un anillo. Básicamente, todos los tipos que piensan como "tipos de números" pertenecen a esta clase:Int
,Double
, etc. verías elNum a =>
restricción frente a una firma si la función se escribió para funcionar genéricamente con cualquier tipo de número. Por ejemplo,sum :: Num a => [a] -> a
, que resume todos los elementos de una lista de números, puede funcionar igualmente bien en[Int]
,[Double]
,[Rational]
, etc ... Todo lo que tiene que hacer es agregar su contenido, sin importar qué tipo de números sean. ¡Pero los números deben ser!
Básicamente, estos tipos de clases/restricciones son un enfoque para la "sobrecarga de principios" de las funciones. Nosotros podemos usar (==) :: Eq a => a -> a -> Bool
en varios tipos, pero no cualquier tipo. Algunas cosas, por ejemplo, las funciones, no tienen sentido comparar la igualdad (tal vez porque la igualdad no es decidible para ese tipo), y nunca tiene sentido comparar dos cosas de diferente Tipos de igualdad (contrasta esto con Java, donde puede comparar dos objetos de tipos posiblemente diferentes para la igualdad).
Para una lectura adicional (muy accesible) sobre clases y restricciones de tipo, recomiendo encarecidamente Aprende un haskell.