
On Sat, Mar 3, 2018 at 1:40 PM, Francesco Ariis
On Sat, Mar 03, 2018 at 12:32:34PM -0800, Hilco Wijbenga wrote:
data Result failure success = Success success | Failure failure
instance Functor (Result failure) where fmap f (Success value) = Success (f value) fmap _ (Failure error) = Failure error -- fmap _ result@(Failure error) = result -- fmap _ result = result
1) Is it possible to define "Result" as "Result success failure" (instead of "Result failure success") and _still_ create an instance of Functor?
Yes, as far the compiler is concerned `data Result failure success` is equivalent to `data Result a b`. Same in your instance, you could have written:
instance Functor (Result a) where -- etc.
no problem.
But now "a" has a different meaning, doesn't it? I had the impression that the "Result a" was similar to currying or leaving a hole (something like " Result a * " but if I change the meaning of "a" from "failure" to "success" then things don't work anymore, do they? In any case, _when_ I flip "success" and "failure" the Functor instance no longer compiles. Which probably makes sense because I did not tell the compiler to interpret "Result failure" as "Result * failure"?
2) The two alternatives for fmap for the Failure scenario do not compile (the end result is "Result failure a" instead of "Result failure b") and that makes sense. But I would like to be able to express that "result" is not touched. Is there any way to do that?
You can but you have to modify your datatype! Probably you want something like this:
data Result r f = Result r (ResState e) data ResState e = Ok | Error e
Ah, I see. Mmm, I'll have to think about that. I prefer the current setup. :-)