Sign up ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free.

I'm studying Haskell for the purpose of understanding functional programming, with the expectation that I'll apply the insight that I gain in other languages (Groovy, Python, JavaScript mainly.)

I choose Haskell because I had the impression that it is very purely functional, and wouldn't allow for any reliance on state.

I did not choose to learn Haskell because I was interested in navigating an extremely rigid type system.

My question is this: Is a strong type system a necessary by-product of an extremely pure functional language, or is this an unrelated design choice particular to Haskell?

share|improve this question

closed as primarily opinion-based by Ixrec, Snowman, MichaelT, jwenting, Robert Harvey May 17 at 20:49

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise.If this question can be reworded to fit the rules in the help center, please edit the question.

If you don't want to explicitly type anything, you don't need to explicitly type anything. Haskell can infer types just fine on its own. And it's not like you're going to have a single variable potentially storing two incompatible types. – Anon. Dec 22 '10 at 3:45
@Anon yes, but your lists must be homogeneous. Trust me, this sort of thing can get in the way, even with type inference. – Eric Wilson Dec 22 '10 at 11:34
@FarmBoy and what is wrong with the use of Maybe? Java really makes you use Maybe on all classes, which is the weird thing to do. – alternative Apr 20 '11 at 22:06
And if you really want to use a heterogeneous list you can of course use algebraic data types. – alternative Apr 20 '11 at 22:14
@mathepic at this point we have really lost track of my original question, which was a perfectly valid question. – Eric Wilson Apr 20 '11 at 22:36

7 Answers 7

up vote 37 down vote accepted

I believe that understanding Haskell's type system is an amplifier to understanding functional programming.

The thing about purely functional programming is that in the absence of side-effects, which allow you to do all sorts of things implicitly, purely functional programming makes the structure of your programs much more explicit.

Haskell prevents you from shoving things under the carpet, forces you to deal with the structure of your program explicitly, and it teaches you a language to describe these structures: the language of types. Understanding types, particularly rich types as is Haskell, will make you a better programmer in any language.

If Haskell wasn't strongly typed, concepts like monads, applicative functors and the like would never have been applied to programming.

share|improve this answer
This is a good answer, my addition is that while the type system may seem unusual at first, later on when you start learning the more advanced concepts you will see that there are certain things that can only be done because of the adherence to that type system (add STM and Data Parallel to the list above). Things that would be non-starters in other type systems fit naturally with the Haskell system. My advice: stick with it for awhile, let it sink in over time (it's not a "cram" language). – anon Dec 7 '11 at 3:05
I know that this is a super old answer, but I actually disagree. I think that, as explicit as some things may be in the language, the type system, especially with monads such as State and Parsec, sweeps a TON of stuff under the carpet. This is actually very greatly interfering with my ability to learn the libraries of the language. – Savanni D'Gerinel Jan 7 '13 at 15:26
@SavanniD'Gerinel: I think in this answer "shoving things under the carpet" does not mean adding implicit functionality (which Haskell does in a controlled way e.g. through monads, and which helps to reduce boilerplate) but rather do allow some piece of code do something it is not expected to do. E.g.: a pure function in Haskell will never have side-effects. Period. In many other languages you can promise this in a function's documentation, but nothing in your language will prevent you from shoving in some side-effects somewhere in your code. – Giorgio Feb 23 '14 at 8:49

Haskell's type system is key to its ability to isolate effects from pure code. Unless you can isolate effects in another way or you remove effects entirely, a strong static type system is a requirement for pure functional programming.

Haskell is a very good example of a language with a strong, static type system. If you want a broad and rounded education in computer science and programming language design in particular, Haskell would be an excellent choice as one of the languages that you should learn.

The type system shouldn't be a huge obstacle. People who program tend to, even when using dynamic languages, follow typing conventions that can be encoded using Haskell's type system. Haskell also features type inference which alleviates verbosity when compared to languages like C++ and Java. When you get an error message, the compiler is only telling you at compile time what a language with dynamic types would tell you at runtime.

The opposite of a dynamic type system is a static type system, not a strong type system. A strong type system is the opposite of a weak type system.

share|improve this answer
For example, C is statically but weakly typed. You have types, but it's easy to subvert the typesystem completely, play around with the underlying machine-specific representations etc. Many dynamically typed languages OTOH are quite strongly typed - few implicit casts, few ways (if any) to subvert the type system. – Steve314 Jun 19 '11 at 2:32

It tells you right away when you make dumb mistakes. This is helpful. I have been working in Racket (Scheme) this last term, and there have been a number of times where I have passed an unparsed s-exp where I expected a parsed ast to some function in my interpreter, and it only showed up in my medium sized test suite. If I had some static typing, it would have been an brought to my attention right away.

Of course, logic errors can't really be caught by the type system, but the number of ways in which you can screw up is greatly diminished.

As well, type inference lets you ignore the type system if you wish. It's still there, but it doesn't require active input on your part. It's still helpful to understand the types of your functions, but correct code will work fine.

Haskell's purity is encoded in its type system. The IO monad is a type level construct that stops impure code from leaking into pure functions, so the purity is guaranteed by the type system.

share|improve this answer
If you think you can ignore Haskell's type system, then I think you haven't coded much Haskell. – Eric Wilson Dec 22 '10 at 11:33
Not ignore so much as ignore it as much as type out the function, load it in GHCi, and go :t on it. But you are still going to need to sprinkle in some fromIntegral or other functions in sometimes. – Theo Belaire Dec 22 '10 at 14:41
Tyr, even with type inference, 90% of using and coding Haskell functions is getting the damned things to mesh with each other, which requires an understanding of its type system and arcane typechecking error messages. Even ":t" is not a magical solution, just the first step to understanding how to make the program compile. – Andres F. Nov 13 '11 at 21:28
Well, some parts are messy, I agree. I really think that the numeric stuff in the prelude could stand to be cleaned up and fixed, because as it stands, it's a terrible mess. But most of the key functional aspects are pretty clean. map, filter, foldr/l, and other fun functional functions work quite nicely. – Theo Belaire Nov 15 '11 at 2:05

The most dynamically typed functional language is arguably Scheme. That said, Haskell's type system is an indicator of its purity. It's a question of "how does one measure purity?". Haskell's type system lets you easily cordon off impure actions in IO. To do that, you need a static type system.

But let's say Haskell's type system has nothing to do with functional programming. It would still be the height of hubris to claim that the type system wouldn't help you in this educational endeavor. Haskell's type system is rich and complex, and all the more interesting when compared to the type systems of C++ and OCaml.

Is it an obstacle? No, I think it is an asset. Try to consider how to deal with Haskell's laziness without IO for example.

share|improve this answer
+1 Haskell's type system can be your friend once you get used to it. – Larry Coleman Dec 22 '10 at 13:24
"To do that, you need a static type system". Really? – Jon Harrop Feb 25 '12 at 19:51
"all the more interesting when compared to the type systems of C++ and OCaml". Have you studied OCaml's first-class higher-order modules and structurally typed inferred object system and polymorphic variants? – Jon Harrop Feb 25 '12 at 19:53
@JonHarrop or an effect system or some way of measuring/evaluating purity. Yep, that's why it's interesting to compare them. Different choices make for different languages. – Logan Capaldo Feb 25 '12 at 20:23

Yes, the type system is an incredible asset. It would be very difficult to even describe how monads work or how some combinators operate without the type system. Consider how many tutorials on Haskell first ask you to consider the type of the function in question with a :t at the REPL. That is simply not available to you in a dynamically typed language. Sure, all the complexity of the type system is still there. A monad is still a monad. But the language has decided to wash its hands of the matter and not provide any help at all. You're on your own, pal. I'm not knocking dynamically typed languages. I love them dearly. Scheme is a power tool par excellance. But you'll notice that when we talk about things like monads in dynamic languages, we often invent a notation for describing the type of procedures. A functional programmer will battle with types one way or the other. Haskell's type checker just gives you good tools to learn how to do that.

share|improve this answer

Clojure is dynamically-typed, and almost as pure as Haskell, so there's a good argument that the Haskell's type system was more of a design choice than an absolute requirement. Both definitely have their strong points, so you may want to consider Clojure if you really don't like Haskell's rigidity (but see below).

When I first started using Haskell, I considered the type system to be annoying, and only tolerated it because of type inference. I soon discovered that many of the type errors the compiler complained about things that wouldn't have worked anyway even if the compiler had let me do them (e.g. accidentally using map instead of concatMap). I then discovered that programs that passed the type check were usually correct, or at least close to correct. I even had a lazy phase where I did refactoring by changing a function type and letting the compiler tell me what else needed to be changed. Finally, I realized that Haskell's type system was actually very expressive and started designing my programs around types. That is the Holy Grail of Haskell.

share|improve this answer
Another thing to note: I learned functional programming using both Scheme and Haskell at about the same time (the former for a class and the latter for fun). I found that understanding recursion was much easier with Haskell's pattern-matching than with ifs and conds in Scheme, which I imagine also carries over to Clojure. – Tikhon Jelvis Dec 6 '11 at 22:10
@Larry Coleman: +1 for describing precisely my own experience with types systems: first C++, then Ocaml, and now my own language Felix. Yes, I still refactor by chasing down compiler errors. – Yttrill Jan 7 '12 at 1:36

Being a "functional" language, means (apart from other things) that functions are first class objects in the language.

Being a "pure" language means that functions are mathematical functions (as opposed to procedures) -- given the same input, they always produce the same output.

A "pure functional language" is one where both the above hold. I am not aware of a "pure-ly functional language".

A strong type system is one clean way of having a pure yet practical language. The types help the compiler figure out optimisations, apart form further ensuring correctness. (But, that isn't the only way -- clojure is pure, but does not have as strong a type system as Haskell.)

If the type system is bothering you, I would suggest you to try a more dynamic language, like Scheme, or get around to using Haskell's type inference system.

share|improve this answer

protected by Robert Harvey May 16 at 2:42

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.