24 votos

¿por qué escribir declaraciones de tipos de Haskell?

Soy nuevo en Haskell y estoy tratando de entender por qué uno tiene que escribir el tipo de declaraciones. Desde Haskell tiene la inferencia de tipos, cuando tengo la primera línea? El INTÉRPRETE parece generar la salida correcta con el uso ':t'

El único ejemplo que he encontrado hasta ahora que parece que necesita una declaración es la siguiente.

maximum' :: (Ord a) => [a] -> a  
maximum' = foldr1 max

Sin embargo, si puedo añadir "-XNoMonomorphismRestriction" bandera de la declaración no es necesario de nuevo. Hay situaciones específicas en la inferencia de tipos no funciona y hay que especificar los tipos?

Ya me podría haber un error en la declaración de tipo y ningún beneficio directo, prefiero no escribir. De nuevo, acabo de empezar a aprender Haskell, así que por favor me corrija si me equivoco, como quiero a desarrollar buenos hábitos.

EDIT: resulta que el Tipo de inferencia es una espada de doble filo de la sección de el Mundo Real Haskell libro tiene una buena discusión de este tema.

28voto

Johannes Weiß Puntos 19013
  • cuando usted tiene grandes Haskell programas, habiendo tipo de firmas a menudo se le da mejor los mensajes de error del compilador
  • en algún momento se puede derivar de lo que una función a partir de su nombre y su firma
  • a menudo una función es comprensible mucho mejor con este tipo de firmas, por ejemplo, si usted hace uso de alarmada
  • incluso la escritura de programas hace más fácil, a menudo empiezo con este tipo de firmas y la mayoría de las funciones declaradas como undefined. Que todo se compila sé que mi idea parece ajuste no es demasiado malo. Luego me voy y reemplace undefined por código real

15voto

alternative Puntos 7053

Considerar read "5". ¿Cómo puede Haskell conocer el tipo de read "5"? No puede, porque no hay manera de resolver el resultado de la operación, ya read se define como (Read a) => String -> a. a no es dependiente de la cadena, por lo que debe contexto de uso.

Sin embargo, generalmente el contexto es algo como Ord o Num , de modo que es imposible determinar. Este no es el monomorphism restricción, sino más bien otro caso que nunca puede ser manejado apropiadamente.

Ejemplos:

No funciona:

read "0.5"
putStrLn . show . read $ "0.5"

No Funciona:

read "0.5" :: Float
putStrLn . show . (read :: String -> Float) $ "0.5"

Estas son necesarias porque el defecto Show de instancia, si recuerdo correctamente, es Int.

5voto

Dan Burton Puntos 26639

La paz de la mente. Es bueno a veces para asegurarse de que el compilador está de acuerdo con su percepción de lo que es una función del tipo debe ser. Si el tipo inferido no unificar con su tipo, el compilador le grite. Una vez que se familiarice con el tipo de sistema, usted encontrará que la opcional de tipo de firmas puede ser una gran ventaja para su codificación confianza.

4voto

Jonathan Sternberg Puntos 2554

Es generalmente porque hace que sea más fácil de leer y, a veces, más fácil de escribir. En un establecimiento inflexible de tipos de lenguaje como Haskell, a menudo te encontrarás a ti mismo haciendo las funciones que toman algunos tipos de salida y de otro tipo y confiar en lo que estos tipos son en lugar de sus nombres. Después de acostumbrarse a cómo el tipo de sistema funciona, se puede hacer más claro lo que se pretende hacer y el compilador puede detectar si se ha hecho algo mal.

Pero esto es una preferencia cosa. Si estás acostumbrado a trabajar en forma dinámica escrito de los idiomas, se puede encontrar la especificación de los tipos no ser más fácil que la especificación de los mismos. Son sólo dos formas diferentes de utilizar la fuerte tipo de sistema de que Haskell proporciona.

A continuación, hay veces cuando la inferencia de tipo no funciona, tales como la de "leer" el ejemplo que dio otra respuesta. Pero esas son de tipo en línea, definiciones, más que la definición de tipo de una función.

2voto

Barend Venter Puntos 351

Una cosa importante que realmente no he visto cubiertos en ninguna de las respuestas es que, a menudo, de hecho, escribir su tipo de definiciones, y tipo de firmas, antes de escribir cualquier código real. Una vez que usted tiene que "especificación" completa, su aplicación será revisada en contra de como se escribe, lo que hará que sea más fácil detectar los errores anteriores como el compilador comprueba que el tipo de partido. Si usted sabe, por ejemplo, que algo debe tener una firma Int -> Int -> [a] -> [a] pero, al escribir, en lugar de instanciar dos parámetros x y y, se crea la instancia de un solo parámetro x por accidente y la use dos veces, el compilador detectará el error en el punto donde se define la función, como contraposición al punto en el que se trató de usarlo cómo se supone que el uso de la misma.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X