views:

460

answers:

3

How to explain Scala's type system to a Haskell expert? What examples show Scala's advantages?

How to explain Haskell's type system to an advanced Scala practitioner? What can be done in Haskell that can't be done in Scala?

+12  A: 

Scala To a Haskell programmer:

Scala is a strict and impure language with first-class modules. New types are declared as modules ("classes"/"traits" with subtle differences). Modules can be type constructors taking universally quantified type parameters. Modules have members which consist of values, mutable variables, and functions (called "methods", to which the module is implicitly passed as a variable called this). Modules may have type members which can also take parameters. Type members can be existentially quantified and type parameters can be higher-kinded.

First-class functions are also modules. A function is a module with a method named apply. A method is not first-class, but a syntax is provided to wrap a method in a first-class function. Unfortunately, a module requires all of its type parameters up front and therefore, as an effect of this method/function dichotomy, a partially applied first-class function is not allowed to be universally quantified.

Instead of type classes with global scope, Scala lets you declare an implicit value of any given type. This includes function types, which provides implicit conversion, and therefore type extension. In addition to implicit conversions, type extension is provided by the "extends" mechanism which lets you declare a subtype/supertype relation among modules. This mechanism can be used to simulate algebraic datatypes where the supertype can be seen as the type on the left-hand side of a data declaration, and its subtypes as the value constructors on the right-hand side. This also means that ADTs are not really closed. Scala has extensive pattern-matching capabilities.

Limited type inference is provided, and improves with each release. Inference of higher kinds appears in Scala 2.8, but without unification of partially applied type constructors.

Haskell to a Scala programmer:

Haskell is a purely functional language. This means that functions are not allowed to have any side-effects at all. For example, a Haskell program doesn't print to the screen as such, but is a function that returns a value of the IO[_] datatype which describes a sequence of actions for the IO subsystem to perform.

Whereas Scala is strict by default and provides "by-name" annotation for nonstrict function arguments, Haskell is lazy by default using "by-need" semantics, and provides annotation for strict arguments.

Type inference in Haskell is more complete than in Scala, having full Hindley-Milner inference, even for partially applied polymorphic type constructors. This means that type annotation is almost never necessary.

Recent extensions to the GHC compiler allow advanced type system features that have no equivalent in Scala, such as rank-n types and type families. An accident of how type classes are resolved by GHC allows type-level equality-checking of types, which in turn allows unordered heterogeneous sets, something that is impossible in Scala.

In Haskell, a module is a collection of types and functions, but modules are not first-class entities. Implicits are provided by type classes, but these are globally scoped once declared, and they cannot be passed explicitly as in Scala. Multiple instances of a given type class for a given type are resolved by the newtype mechanism whereas in Scala this would be solved simply by scoping or by passing instances explicitly.

Since Haskell isn't "object-oriented", there's no method/function dichotomy. Every function is first class and every function is curried by default (no Function1, Function2, etc).

Apocalisp
Can you provide some examples?
Łukasz Lew
Can you please explain Haskell from a Scala developer's perspective?
missingfaktor
Thanks a lot! :-)
missingfaktor
@Apocalisp: Higher-order unification is undecidable and even when a unifier can be found, the MGU is not uniquely defined. At best this seems to leave a deeply embedded non-determinism in Haskell. What use is made of higher-order unification in Haskell and how are its tractability and non-uniqueness issues handled?
Randall Schulz
Randall: It's entirely possible that I'm conflating HOU with whatever mechanism of unifying partially applied type constructors is available in GHC Haskell. Changing the answer to reflect this.
Apocalisp
+2  A: 

I don't believe anyone has systematically compared Haskell (as exemplified by GHC's type system) with Scalas. The main points of difference are the degree of type inference, and support for higher-rank types. But a full treatment of the differences would be a publishable result.

Don Stewart
+1  A: 

My friend send me this link. Examples in this blog post are very interesting.

Łukasz Lew
Be aware that this blog post of Tony's (and he knows what he's talking about) is 2 1/2 years old, now, and Scala has progressed significantly since then, especially if you count the not-yet-released Scala 2.8 as the current language.
Randall Schulz