scala haskell type-systems

¿Cuáles son las diferencias y similitudes de los sistemas de tipo Scala y Haskell?



type-systems (2)

¿Cómo explicar el sistema de tipos de Scala a un experto en Haskell? ¿Qué ejemplos muestran las ventajas de Scala?

¿Cómo explicar el sistema de tipos de Haskell a un practicante avanzado de Scala? ¿Qué se puede hacer en Haskell que no se puede hacer en Scala?


No creo que nadie haya comparado sistemáticamente a Haskell (como lo ejemplifica el sistema de tipos de GHC) con Scalas. Los principales puntos de diferencia son el grado de inferencia de tipo y el soporte para tipos de rango superior. Pero un tratamiento completo de las diferencias sería un resultado publicable.


Scala a un programador de Haskell:

Scala es un lenguaje estricto e impuro con módulos de primera clase. Los tipos de datos se declaran como "clases" o "rasgos" con diferencias sutiles, y los módulos u "objetos" son valores de esos tipos. Scala admite constructores de tipos que toman parámetros de tipo universalmente cuantificados. Los objetos / clases / rasgos tienen miembros que consisten en valores, variables mutables y funciones (llamadas "métodos", a los que el módulo se pasa implícitamente como una variable llamada this ). Los módulos pueden tener miembros de tipo que también pueden tomar parámetros. Los miembros de tipo se cuantifican existencialmente y los parámetros de tipo pueden ser de mayor valor. Debido a que los tipos pueden ser miembros de los valores de primera clase, Scala proporciona un sabor de tipado dependiente llamado tipos dependientes de la ruta .

Las funciones de primera clase también son módulos. Una función es un módulo con un método llamado apply . Un método no es de primera clase, pero se proporciona una sintaxis para ajustar un método en una función de primera clase. Desafortunadamente, un módulo requiere todos sus parámetros de tipo por adelantado, por lo tanto, no se permite que una función de primera clase parcialmente aplicada sea universalmente cuantificada. De manera más general, Scala carece por completo de un mecanismo directo para tipos de rango superiores a 1, pero los módulos parametrizados en tipos de mayor grado pueden aprovecharse para simular tipos rank-n.

En lugar de escribir clases con alcance global, Scala le permite declarar un valor implícito de cualquier tipo dado. Esto incluye tipos de funciones, que proporcionan conversión implícita y, por lo tanto, tipo de extensión. Además de las conversiones implícitas, la extensión de tipo es provista por el mecanismo "extends" que le permite declarar una relación subtipo / supertipo entre los módulos. Este mecanismo se puede usar para simular tipos de datos algebraicos donde el supertipo se puede ver como el tipo en el lado izquierdo de una declaración de datos, y sus subtipos como los constructores de valores en el lado derecho. Scala tiene amplias capacidades de coincidencia de patrones mediante el uso de un matcher de patrones virtualizado con patrones de primera clase.

Scala admite la subtipificación, y esto limita considerablemente la inferencia de tipo. Pero la inferencia de tipos ha mejorado con el tiempo. Se admite la inferencia de tipos de mayor nivel. Sin embargo, Scala carece de cualquier sistema amable significativo, y por lo tanto no tiene una inferencia amable ni una unificación amable. Si se introduce una variable de tipo, es de tipo * menos que se indique lo contrario. Ciertos tipos como Any (el supertipo de todos los tipos) y Nothing (un subtipo de cada tipo) son técnicamente de todo tipo, aunque no se pueden aplicar a los argumentos de tipo.

Haskell a un programador de Scala:

Haskell es un lenguaje puramente funcional. Esto significa que las funciones no tienen ningún efecto secundario. Por ejemplo, un programa Haskell no se imprime en la pantalla como tal, sino que es una función que devuelve un valor del tipo de datos IO[_] que describe una secuencia de acciones para que el subsistema IO realice.

Mientras que Scala es estricto por defecto y proporciona una anotación "por nombre" para argumentos de funciones no estrictas, Haskell es flojo por defecto usando semántica "por necesidad" y proporciona anotaciones para argumentos estrictos.

La inferencia de tipo en Haskell es más completa que en Scala, teniendo una inferencia completa. Esto significa que la anotación de tipo casi nunca es necesaria.

Las extensiones recientes del compilador de GHC permiten características avanzadas del sistema de tipos que no tienen equivalente en Scala, como los tipos de rango n, familias de tipos y polimorfismo de clases.

En Haskell, un módulo es una colección de tipos y funciones, pero los módulos no son entidades de primera clase. Los implicits son proporcionados por clases de tipo, pero estos tienen un ámbito global una vez declarados, y no se pueden pasar explícitamente como en Scala. Múltiples instancias de una clase de tipo para un tipo dado se resuelven envolviendo con un newtype para desambiguar, mientras que en Scala esto se resolvería simplemente por alcance o pasando instancias explícitamente.

Como Haskell no está "orientado a objetos", no hay una dicotomía método / función. Cada función es de primera clase y cada función está currificada por defecto (sin función1, función2, etc.).

Haskell no tiene mecanismo de subtipo, pero las clases de tipo pueden tener una relación de subclase.