Search code examples
haskellfunctional-programmingmonadsoption-typeeither

Why Do We Need Maybe Monad Over Either Monad


I was playing around Maybe and Either monad types (Chaining, applying conditional functions according to returned value, also returning error message which chained function has failed etc.). So it seemes to me like we can achieve same and more things that Maybe does by using Either monad. So my question is where the practical or conceptual difference between those ?


Solution

  • You are of course right that Maybe a is isomorphic to Either Unit a. The thing is that they are often semantically used to denote different things, a bit like the difference between returning null and throwing a NoSuchElementException:

    • Nothing/None denotes the "expected" missing of something, while
    • Left e denotes an error in getting it, for whatever reason.

    That said, we might even combine the two to something like:

    query :: Either DBError (Maybe String)
    

    where we express both the possibility of a missing value (a DB NULL) and an error in the connection, the DBMS, or whatever (not saying that there aren't better designs, but you get the point).

    Sometimes, the border is fluid; for saveHead :: [a] -> Maybe a, we could say that the expected possibility of the error is encoded in the intent of the function, while something like saveDivide might be encoded as Float -> Float -> Either FPError Float or Float -> Float -> Maybe Float, depending on the use case (again, just some stupid examples...).

    If in doubt, the best option is probably to use a custom result ADT with semantic encoding (like data QueryResult = Success String | Null | Failure DBError), and to prefer Maybe to simple cases where it is "traditionally expected" (a subjective point, which however will be mostly OK if you gain experience).