2009-11-29 17 views

Respuesta

95

Scala Para un programador 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 valores de primera clase, Scala proporciona un sabor de tipado dependiente llamado path-dependent types.

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 la inferencia de tipo considerablemente. 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 del tipo * a 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 todos los tipos aunque no se pueden aplicar a los argumentos de tipo.

Haskell a un programador 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 la 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 GHC permiten funciones avanzadas del sistema de tipos que no tienen equivalente en Scala, como los tipos rank-n, familias de tipos y polimorfismos 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. Varias instancias de una clase de tipo para un tipo dado se resuelven envolviendo con newtype para desambiguar, mientras que en Scala esto se resolvería simplemente por alcance o pasando instancias explícitamente.

Dado que Haskell no está "orientado a objetos", no existe 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.

+0

¿Puede proporcionarnos algunos ejemplos? –

+0

¿Puede explicar Haskell desde la perspectiva de un desarrollador de Scala? – missingfaktor

+0

@Apocalisp: la unificación de orden superior es indecidible e incluso cuando se puede encontrar un unificador, la MGU no está definida de forma exclusiva. En el mejor de los casos, esto parece dejar un no determinismo profundamente arraigado en Haskell. ¿Qué uso se hace de la unificación de orden superior en Haskell y cómo se manejan sus problemas de manejabilidad y no exclusividad? –

6

No creo que nadie haya comparado sistemáticamente 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.

+3

¿Sabe si se ha publicado tal tratamiento en los seis años posteriores a esta publicación? Me interesaría leer el periódico. –

Cuestiones relacionadas