27

Scala and Haskell have "Turing complete type systems". Usually, Turing completeness refers to computations and languages. What does it really mean in the context of types?

Could some one give an example of how a programmer can benefit from it?

PS I don't want to compare Haskell's vs Scala's type systems. It's more about the term in general.

PSS If it's possible more Scala examples.

Community
  • 1
  • 1
Sayat Satybald
  • 6,300
  • 5
  • 35
  • 52
  • 5
    Your question is largely answered in [What makes Haskell's type system more “powerful” than other languages' type systems?](http://stackoverflow.com/questions/3787960/what-makes-haskells-type-system-more-powerful-than-other-languages-type-syst) -- it even uses Scala as a comparison, discusses Turing-completeness and gives examples. – sshine Nov 30 '15 at 16:00
  • 1
    Basically, it means you can calculate stuff at compile-time. The canonical example being containers with static sizes fixed at compile-time, and being able to statically calculate the result of concatenating two such containers. – MathematicalOrchid Nov 30 '15 at 16:11

1 Answers1

33

What does it really mean in the context of types?

It means the type system has enough features in it to represent arbitrary computations. As a very short proof, I present below a type-level implementation of the SK calculus; there are many places that discuss the Turing-completeness of this calculus and what it means, so I won't rehash that here.

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE TypeOperators #-}

infixl 1 `App`
data Term = S | K | App Term Term

type family Reduce t where
    Reduce S = S
    Reduce K = K
    Reduce (S `App` x `App` y `App` z) = Reduce (x `App` z `App` (y `App` z))
    Reduce (K `App` x `App` y) = Reduce x
    Reduce (x `App` y) = Reduce (Reduce x `App` y)

You can see this in action at a ghci prompt; for example, in the SK calculus, the term SKSK reduces (eventually) to just K:

> :kind! Reduce (S `App` K `App` S `App` K)
Reduce (S `App` K `App` S `App` K) :: Term
= 'K

Here's a fun one to try as well:

> type I = S `App` K `App` K
> type Rep = S `App` I `App` I
> :kind! Reduce (Rep `App` Rep)

I won't spoil the fun -- try it yourself. But know how to terminate programs with extreme prejudice first.

Could some one give an example how a programmer can benefit from it?

Arbitrary type-level computation allows you to express arbitrary invariants on your types, and have the compiler verify (at compile-time) that they are preserved. Want a red-black tree? How about a red-black tree that the compiler can check preserves the red-black-tree invariants? That would be handy, right, since that rules out a whole class of implementation bugs? How about a type for XML values that is statically known to match a particular schema? In fact, why not go a step further and write down a parameterized type whose parameter represents a schema? Then you could read in a schema at runtime, and have your compile-time checks guarantee that your parameterized value can only represent well-formed values in that schema. Nice!

Or, perhaps a more prosaic example: what if you wanted your compiler to check that you never indexed your dictionary with a key that wasn't there? With a sufficiently advanced type system, you can.

Of course, there's always a price. In Haskell (and probably Scala?), the price of a very exciting compile-time check is spending a great deal of programmer time and effort convincing the compiler that the thing you're checking is true -- and this is often both a high up-front cost as well as a high ongoing maintenance cost.

Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380
  • 3
    I completely agree on Haskell highlighting being dull. I'd love if at least `Uppercase` words got a different color. however, I must also confess that I really dislike those highlighters who insist on coloring non-keywords such as `print` as if they were "special". – chi Nov 30 '15 at 17:16
  • 2
    That you have to spend so much effort convincing the type system to prove stuff for you is isomorphic to a statement that the language for specifying type computations is not as powerful as you'd like. – Rex Kerr Nov 30 '15 at 17:26
  • 4
    @RexKerr I'm not so sure. I think any professor will tell you that it can take quite some convincing to get a grad student to do a particular bit of work for you; and the language for communicating with grad students is quite rich and powerful indeed. Or, grounding ourselves back in type systems for a moment: some proofs are just hard! – Daniel Wagner Nov 30 '15 at 19:29
  • 1
    Some proofs are hard, but that's not an excuse for making easy tasks hardto express. As an existence proof: I generally find it a lot easier to write proofs in Mathematica than in types in Scala or Haskell. – Rex Kerr Nov 30 '15 at 19:49
  • 1
    @RexKerr If your real claim is that Haskell's proof language is subpar, well, I'm certainly not going to argue with that! It was very much bolted on after-the-fact. – Daniel Wagner Nov 30 '15 at 20:20
  • 2
    @RexKerr, informal proofs in Mathematica aren't really comparable to formal ones. It's somewhat more fair to judge Haskell against something like Agda, although Haskell is not intended to be entirely sound in the same sense. – dfeuer Nov 30 '15 at 20:35
  • 1
    @dfeuer - Mathematica does formal proofs and has since version 6. Or else what do you call https://www.wolfram.com/products/mathematica/newin6/content/EquationalTheoremProving/ProveAnAbstractAlgebraicTheorem.html – Rex Kerr Nov 30 '15 at 22:31