2 ms·
That's an outrageously overwrought type, though. Let's say a promise is a thing which can either succeed or fail eventually. If it fails, it gives a type e, if
by tel 12y ago
That's an outrageously overwrought type, though.
Let's say a promise is a thing which can either succeed or fail eventually. If it fails, it gives a type e, if it succeeds a type a
Promise e a
Now, `then` operates on the successful result, transforming it into a new promise of a different kind. The result is a total promise of the new kind
then :: Promise e a -> (a -> Promise e b) -> Promise e b
I'll contest now that this is sufficient. Here's what you appear to lose:
1. No differentiation of error types
2. No explicit annotation of the ability to
return constant/non-promise values
3. No tied-in error handling
That's fine, though. First, for (1), we'll note that it ought to be easy to provide an error-mapping function. This is just a continuation which gets applied to errors upon generation (if they occur)
mapError :: (e -> e') -> Promise e a -> Promise e' a
For (2) we'll note that it's always possible to turn a non-promised value into a promise by returning it immediately
pure :: a -> Promise e a
Then for (3), we can build in error catching continuations
catch :: Promise e a -> (e -> Promise e' a) -> Promise e a
We appear to lose the ability to change the result type of the promise upon catching an error, but we can regain that by pre-composition with `then`.
So, each of these smaller types is now very nice to work with. They are equivalent in power to the fully-loaded `then` you gave, but their use is much more compartmentalized. This is how you avoid frightful types.
- lomnakkus 12y agoCouldn't agree more. I see this as just another example of how ordinary function composition usually wins out over OOP. Additionally, AFAICT Promise-like things aren't actually used very much in Haskell in practice; at least not in the code I tend to see/write. MVar is probably the nearest direct equivalent, modulo error handling (which would probably just be handled using an Either in an MVar). Given that the runtime is M:N threaded, there doesn't seem to be much need for Promise and its ilk, since you can just do ordinary function composition and HoFs (with channels for communication). If you want something fancy you just use the marvellous "async" library.