Quelles sont les différences et les similitudes entre les systèmes de type Scala et Haskell?

Comment expliquer le système de saisie de Scala à un expert Haskell? Quels exemples montrent les avantages de Scala?

Comment expliquer le système de caractères de Haskell à un praticien Scala avancé? Que peut-on faire à Haskell qui ne peut pas être fait à Scala?

Scala À un programmeur Haskell:

Scala est un langage ssortingct et impur avec des modules de première classe. Les types de données sont déclarés comme “classes” ou “traits” avec des différences subtiles et les modules ou “objects” sont des valeurs de ces types. Scala prend en charge les constructeurs de types prenant des parameters de type quantifiés universellement. Les objects / classes / traits ont des membres constitués de valeurs, de variables mutables et de fonctions (appelées “méthodes”, auxquelles le module est implicitement passé en tant que variable appelée this ). Les modules peuvent avoir des membres de type qui peuvent également prendre des parameters. Les membres de type sont quantifiés de manière existentielle et les parameters de type peuvent être plus élevés. Étant donné que les types peuvent être membres de valeurs de première classe, Scala fournit une saveur de type dépendant appelé type dépendant du chemin .

Les fonctions de première classe sont également des modules. Une fonction est un module avec une méthode nommée apply . Une méthode n’est pas de première classe, mais une syntaxe est fournie pour envelopper une méthode dans une fonction de première classe. Malheureusement, un module nécessite tous ses parameters de type, de sorte qu’une fonction de première classe partiellement appliquée n’est pas autorisée à être quantifiée universellement. Plus généralement, Scala ne dispose pas d’un mécanisme direct pour les types de rangs supérieurs à 1, mais des modules paramétrés sur des types plus élevés peuvent être exploités pour simuler des types de rang n.

Au lieu de classes de type avec une scope globale, Scala vous permet de déclarer une valeur implicite de tout type donné. Cela inclut les types de fonctions, qui fournissent une conversion implicite, et par conséquent, l’extension de type. En plus des conversions implicites, l’extension de type est fournie par le mécanisme “extend” qui vous permet de déclarer une relation sous-type / supertype entre les modules. Ce mécanisme peut être utilisé pour simuler des types de données algébriques où le supertype peut être vu comme le type situé à gauche d’une déclaration de données et ses sous-types comme constructeurs de valeurs du côté droit. Scala dispose de nombreuses fonctionnalités de correspondance de modèles utilisant un gestionnaire de modèle virtualisé avec des modèles de première classe.

Scala prend en charge le sous-typage, ce qui limite considérablement l’inférence de type. Mais l’inférence de type s’est améliorée avec le temps. L’inférence des types supérieurs est prise en charge. Cependant, Scala ne dispose d’aucun système bienveillant et n’a donc aucune inférence aimable ni aucune unification. Si une variable de type est introduite, elle est de nature * sauf indication contraire. Certains types, comme Any (le sur-type de tous les types) et Nothing (un sous-type de chaque type), sont techniquement de toutes sortes, bien qu’ils ne puissent pas être appliqués aux arguments de type.

Haskell à un programmeur Scala:

Haskell est un langage purement fonctionnel. Cela signifie que les fonctions ne peuvent avoir aucun effet secondaire. Par exemple, un programme Haskell n’imprime pas à l’écran en tant que tel, mais est une fonction qui renvoie une valeur du type de données IO[_] qui décrit une séquence d’actions à effectuer par le sous-système IO.

Alors que Scala est ssortingcte par défaut et fournit une annotation “par nom” pour les arguments de fonction non ssortingcts, Haskell est paresseux par défaut en utilisant la sémantique “par besoin” et fournit des annotations pour des arguments ssortingcts.

L’inférence de type dans Haskell est plus complète que dans Scala, ayant une inférence complète. Cela signifie que l’annotation de type n’est presque jamais nécessaire.

Les extensions récentes du compilateur GHC permettent des fonctionnalités système de type avancé sans équivalent dans Scala, telles que les types rank-n, les familles de types et les polymorphisms de types.

Dans Haskell, un module est une collection de types et de fonctions, mais les modules ne sont pas des entités de première classe. Les implicits sont fournis par les classes de type, mais celles-ci sont globalement définies une fois déclarées, et elles ne peuvent pas être transmises explicitement comme dans Scala. Plusieurs instances d’une classe de type pour un type donné sont résolues en encapsulant un newtype pour désambiguïser, alors que dans Scala, cela serait résolu simplement en explorant ou en transmettant explicitement des instances.

Puisque Haskell n’est pas “orienté object”, il n’y a pas de dichotomie méthode / fonction. Chaque fonction est de première classe et chaque fonction est définie par défaut (pas de fonction1, fonction2, etc.).

Haskell n’a pas de mécanisme de sous-type, mais les classes de type peuvent avoir une relation de sous-classe.

Je ne crois pas que quiconque ait comparé systématiquement Haskell (comme le montre le système de caractères de GHC) avec Scalas. Les principaux points de différence sont le degré d’inférence de type et le support pour les types de rang supérieur. Mais un traitement complet des différences serait un résultat publiable.