Why can AccValidation not have a Monad instance?

前端 未结 2 497
野的像风
野的像风 2021-01-02 16:57

From the documentation of the validation package:

The AccValidation data type is isomorphic to Either, but has an instance of <

2条回答
  •  粉色の甜心
    2021-01-02 17:32

    Mechanically, the Either-ish Monad instance for AccValidation would be

    -- The (Monoid err) context is not used for anything, 
    -- it's just there to satisfy the Applicative super-instance
    instance (Monoid err) => Monad (AccValidation err) where
        return = AccSuccess
        AccFailure err >>= f = AccFailure err
        AccSuccess x >>= f = f x
    

    which would mean we have

    AccFailure err1 <*> AccFailure err2 = AccFailure (err1 <> err2)
    AccFailure err1 `ap` AccFailure err2 = AccFailure err1
    

    which breaks the monad law of <*> = ap.

    Intuitively, it can't be made a monad because in a monad, the effect (i.e. the validation failures) of a computation can depend on previously bound results. But in the case of a failure, there is no result. So Either has no choice than to short-circuit to failure in that case, since there is nothing to feed to the subsequent functions on right-hand sides of (>>=)s.

    This is in stark contrast to applicative functors, where the effect (in this case, the validation failures) cannot depend on other results, which is why we can get all validation failures without having to feed results (where would they come from?) from one computation to the other.

提交回复
热议问题