
For sum types you need a way to construct them and pattern match them. Without a way to _name_ them, it would probably look like this:
showError :: (Result | Error3 | Error8) -> String showError (result ||) = "no error" showError (| error3 |) = "error3: " ++ show error3 showError (|| error8 |) = "error8: " ++ show error8
It's not the most readable code, so I'd generally avoid using it for anything greater than 3 (same applies to tuples).
I doubt that functions usually cause more than one or two different errors. Unless you count undefined, asyncronous ... But you don't want those in your type anyway (too verbose).
It also suffers the same flaw as tuples: no way to extend them easily. Imagine adding a new error: you have to edit _all_ of the patterns:
showError :: (Result | Error3 | Error8 | Error11 ) -> String showError (result |||) = "no error" showError (| error3 ||) = "error3: " ++ show error3 showError (|| error8 |) = "error8: " ++ show error8 showError (||| error11 ) = "error11: " ++ show error11
Extensible records and variants might be able to solve these problems, but that's a rabbit-hole of its own though.
Yes of course, but wouldn't you still agree that tuples are useful. So would sum tuples be. Additionally, tuple like structures can easily be simulated using type operators data a :' b = a :' b However, the pattern matching for even a 3-way sum type using Either will be a nightmare. And I see no way of simulating this without using Template Haskell. type ... a = a `Either` Int `Either` Char Left (Right int) ??? or Right (Left int) ??? Silvio