The author is complaining about two language extensions which are present in GHC. These extensions are not part of the Haskell language, which is defined at http://www.haskell.org/onlinereport/haskell2010/ .
The first language extension is the function 'unsafePerformIO', defined in the module 'System.IO.Unsafe'. It's not defined in the language spec, and is unsafe by design because it's intended for very rare and specific use cases in performance-critical code.
The second language extension is the 'Data.Typeable' module, which defines a mechanism of dynamic typing. The standard way to use Typeable is to let the compiler define the instance, which is both safe and much easier to type. It's well-known that implementing a Typeable instance manually is unsafe; for example, see Oleg's post from 2007 http://okmij.org/ftp/Haskell/types.html#unsound-typeable .
Again, these are extensions to the language, implemented as experiments by a particular compiler. A program which uses them is no longer standard Haskell.
His code does not compile when built in standard Haskell mode:
$ ghc --make exc.hs -hide-all-packages -package haskell2010
exc.hs:2:8:
Could not find module `Data.Typeable'
Indeed, this problem has absolutely nothing to do with exceptions, other than that exceptions require the Typeable typeclass. I suspect the author only roped exceptions into his exposition to give him an excuse for that linkbaity title.
The problem isn't even caused by Typeable itself per se, it's caused by wilfully ignoring that you're not meant to define an instance of it manually, you're meant to tell the compiler to derive one automatically. As far as I'm aware, writing your own Typeable instance causes undefined behaviour according to the very specification of the typeclass.
So, yes, Haskell's types are unsafe, if you deliberately go out of your way to subvert them. I'm left wondering... "So what?"
While what you say is true, GHC is the de facto Haskell standard. At least the last time I looked, most widely used and well respected Haskell code would only work in GHC using various extensions. That's the actual state of Haskell: GHC with non-standard extensions is the effective standard.
An extension that GHC provides, and therefore part of the effective standard, is Safe Haskell (http://www.haskell.org/ghc/docs/7.4.2/html/users_guide/safe-...). A Safe (compiled with -XSafe, containing the LANGUAGE Safe pragma, or inferred) module may not define any manual instances of Typeable.
This is all true, but his actual point is that exception handling should not involve Data.Typeable (or any type casting) at all. I do feel this is an extremely obscure point that does not justify this hyperbole, but it is his blog and he is free to decide what is important there.
From his post, it appears that ML handles exceptions by allowing code to add new constructors to the 'exc' type at run-time. This is effectively indistinguishable from the GHC implementation of dynamic typing, which uses typeclasses.
Without some sort of dynamic type casting as used in ML or Haskell, then it's not possible to implement an exception handler that can extract information (such as type) about an exception. All you'd be able to determine is "some exception was thrown".
Yes, ML is adding new constructors to exn type at runtime, but this is different from GHC implementation of dynamic typing which uses typeclasses, because GHC does not add typeclasses at runtime. Take a look at ezyang(who is a GHC developer)'s comments in the post.
I repeat that this is extremely obscure and probably only interesting to people like ezyang. He is engaged in the discussion, so I guess the post was not pointless.
He somewhat obscures that point with tangentially-relevant grumbling and dead-horse-beating, if indeed that's the point he was trying to make (I guess I can see it, looking at the submission again with that interpretation in mind) -- you've made it more clearly in a paragraph than he did in a whole blog post.
Actually, as far as I'm aware, IO exceptions don't see much use in practice -- they aren't considered very "Haskell-y". In fact, that's partly because of the dynamic typing aspect that this whole discussion centres around; but also because their behaviour is dependent on evaluation order, and because the possibility of an expression throwing one isn't encoded in that expression's type. None of that is really in the spirit of idiomatic Haskell.
As such, MonadError is the way exception-like behaviour tends to be handled, AFAIK.
I would say `unsafePerformIO` exist for calling C code. Since the Haskell type system can't prove that the C function you're calling is pure, the programmer needs to assert this fact by using `unsafePerformIO` at the call site. There are other possible uses of course, but I'd say this is the main one.
The first language extension is the function 'unsafePerformIO', defined in the module 'System.IO.Unsafe'. It's not defined in the language spec, and is unsafe by design because it's intended for very rare and specific use cases in performance-critical code.
The second language extension is the 'Data.Typeable' module, which defines a mechanism of dynamic typing. The standard way to use Typeable is to let the compiler define the instance, which is both safe and much easier to type. It's well-known that implementing a Typeable instance manually is unsafe; for example, see Oleg's post from 2007 http://okmij.org/ftp/Haskell/types.html#unsound-typeable .
Again, these are extensions to the language, implemented as experiments by a particular compiler. A program which uses them is no longer standard Haskell.
His code does not compile when built in standard Haskell mode: