2011-06-15 10 views
5

¿Cómo definiría las siguientes firmas de tipos en la llanura Inglés:tipo de listas, etc.

Ord a => ... 

Eq a => ... 

Num a => ... 

Podría describir el significado de estas y que me haga saber cuáles son las diferencias (en términos de cómo se lo explicaría a alguien más)?

Gracias.

Respuesta

13

Todos estos son ejemplos de "restricciones de clase": éstos limitan qué tipos se puede utilizar en lugar de la variable tipo que los sigue (a en este caso), lo que requiere que pertenecen a un determinado type class. Ord, Eq y Num son ejemplos de clases de tipos.

  • Ord a => ... significa a es un tipo que tiene una noción natural de orden asociado con él. Por ejemplo, los enteros se pueden organizar de forma natural de menor a mayor. En términos matemáticos, existe un total order en a. Un ejemplo obvio de una función que requiere esta restricción es sort :: Ord a => [a] -> [a]; lea esta firma que dice que sort solo funciona en listas de cosas que pueden ordenarse entre sí.

  • Eq a => ... es un tipo cuyos miembros se pueden comparar entre sí por alguna noción de igualdad. En términos matemáticos, existe un equivalence relation en a. Tenga en cuenta que esta es una superclase de Ord, lo que significa que cualquier cosa que tenga una noción de orden también debe tener una noción de equivalencia. Un ejemplo de una función que requiere esta restricción es elem :: Eq a => a -> [a] -> Bool (que determina si una lista contiene un elemento dado); lea esta firma como diciendo que elem solo funciona en listas de cosas que se pueden comparar entre sí por igualdad. Si piensas en cómo escribirías elem, eso debería tener sentido.

  • Num a => ... significa a es un tipo numérico, lo que significa que es compatible con algunas operaciones aritméticas básicas: +, *, -, abs. Creo que esto es más o menos similar a la noción matemática de ring. Básicamente, todos los tipos que considera "tipos de número" pertenecen a esta clase: Int, Double, etc. Vería la restricción Num a => delante de 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 suma 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 sumar su contenido, sin importar qué tipo de números sean . ¡Pero los números deben ser!

Básicamente, estas clases de tipos/limitaciones son una aproximación a la "sobrecarga de principios" de funciones. Podemos usar (==) :: Eq a => a -> a -> Bool en varios tipos, pero , no solo cualquier tipo. Algunas cosas, por ejemplo funciones, no tienen sentido comparar para igualdad (quizás porque la igualdad no es decidible para ese tipo), y nunca tiene sentido comparar dos cosas de diferentes tipos de para igualdad (contraste esto con Java, donde puede comparar dos objetos de tipos posiblemente diferentes para la igualdad).

Para obtener más lecturas (muy accesibles) sobre clases de tipo y restricciones, recomiendo Learn You a Haskell.

+0

Creo que las personas a menudo esperan que '(==)' sea una relación de congruencia más que una relación de equivalencia. Por supuesto, Haskell tampoco te obliga a hacerlo. – augustss

Cuestiones relacionadas