I write #fsharp and #haskell daily (and #purescript too) and thought of making a micro-blog comparison of the two. Fun facts and maybe new discoveries for the interested, in no particular order. This will be long and probably slow.
Unlike #fsharp, #haskell has no records, only discriminated unions. It does have something called “record syntax” for DUs.
In #fsharp functions cannot be overloaded. In #haskell it is possible through the “type classes” mechanism, conceived specifically for this.
#fsharp compiler derives (generates) equality for user-defined types with an opt-out option. #haskell can also derive equality, but it is opt-in. So by default values of the same time cannot be equality-compared in Haskell.
Modules in #haskell are both better and worse than in #fsharp. One convenient feature is that a module (say A) can re-export another module (say its dependency B). Clients of A then don’t have to import B to use something from it alongside stuff from A.
Pattern matching is more powerful in #fsharp than in #haskell which lacks AND and OR patterns.
In #fsharp all types are declared using the uniform keyword “type”. In #haskell there are actually three related keywords: “type”, “data” and “newtype”.
#fsharp is compiled to .NET IL and after that subject to JIT compulation by the runtime. #haskell is fully AOT compiled to native binaries.
As per CLR normal, #fsharp preserves type information in compiled output. #haskell performs type erasure. This means, a.o. that there is no run-time reflection possible in Haskell.
In #fsharp there are separate ‘map’ functions for lists, options and so on. Similarly for ‘filter, ‘fold’ and many more. In #haskell there is (effectively) a single “map” function, but it is polymorphic enough to work with all “mappable types”.
In #fsharp mutable variables are marked with keyword "mutable". In #haskell mutable variables have a dedicated type.
Despite the above tweet, unlike #fsharp, #haskell is famously a pure FP language. Even more famously, it is the only(?) widely used, general purpose PL with lazy evaluation.
Both #fsharp and #haskell have algebraic data types (ADT). In addition, Haskell also has "Generalized ADT" (GADT). Basically in F# terms, one can define a polymorphic DU like FormInput<'a>, but DU constructors limit what 'a can be, e.g. 'int' or 'string' and nothing else.
• • •
Missing some Tweet in this thread? You can try to
force a refresh