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

2

@Anon yes, but your lists must be homogeneous. Trust me, this sort of thing can get in the way, even with type inference.
–
Eric WilsonDec 22 '10 at 11:34

@FarmBoy why in the world would you ever want a non-homogeneous list on the first place? Either have a homogeneous list (maybe use a typeclass) or a heterogeneous tuple.
–
alternativeApr 20 '11 at 18:18

12

@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.
–
alternativeApr 20 '11 at 22:06

2

And if you really want to use a heterogeneous list you can of course use algebraic data types.
–
alternativeApr 20 '11 at 22:14

12 Answers
12

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.

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).
–
anonDec 7 '11 at 3:05

2

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'GerinelJan 7 '13 at 15:26

1

@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.
–
GiorgioFeb 23 '14 at 8:49

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.

"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 HarropFeb 25 '12 at 19:53

2

@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 CapaldoFeb 25 '12 at 20:23

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.

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 JelvisDec 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.
–
YttrillJan 7 '12 at 1:36

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.

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.
–
Steve314Jun 19 '11 at 2:32

I tried to express that in the question. I'm not sure where it got lost. I'll try again. X = "learning functional programming". Y = "learning an intricate type system". X was my goal. Quickly I found myself spending considerable time in Y. I was unsure whether Y was helping me to accomplish X. If X could be accomplished well without Y, perhaps I would be interested in that.
–
Eric WilsonMar 21 '11 at 16:16

2

Ok. You want to learn functional programming. But "function" is just a name for a large class of types, so to speak. For example, Int -> Int is a thing that, when applied to an Int, will give you an Int. It is hard to see how to learn functional programming without ever thinking about the types of the functions one writes.
–
IngoMar 21 '11 at 17:08

+1 - nice point about "unityped". C# 4 even has a static type called "dynamic", which is intended to allow easier interop with dynamic languages.
–
Steve314Jun 19 '11 at 2:28

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.

If you think you can ignore Haskell's type system, then I think you haven't coded much Haskell.
–
Eric WilsonDec 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 BelaireDec 22 '10 at 14:41

1

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 BelaireNov 15 '11 at 2:05

All the languages you mentioned are dynamically typed so learning haskell is going to be pretty tough if haskell is your first exposure to static typing and functional programming in general. You're probably better off starting with Erlang which is a functional language but doesn't have the same restrictive type system as haskell.

I'm most experienced in Java, so static typing isn't new to me.
–
Eric WilsonDec 22 '10 at 11:33

7

@FarmBoy: But good static typing probably is :-) Haskell's type system is nothing like Java's. Java's type system, particularly after using Haskell, feels like using a straightjacket; Haskell's type system adds features to the language. Don't immediately turn against static typing because Java's version of it sucks.
–
Antal S-ZDec 24 '10 at 6:14

1

It's not Java's type system that is the problem, its the object oriented rubbish that forces you to try to convolute a fairly obvious and correct solution into a framework which provably cannot provide one. The typing simply enforces the fraudulent design concept.
–
YttrillJan 7 '12 at 1:41

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.

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.