Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Do We Need Maybe Monad Over Either Monad

Tags:

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 ?

like image 712
altayseyhan Avatar asked Mar 02 '17 11:03

altayseyhan


People also ask

Why do we need monad?

monads are used to address the more general problem of computations (involving state, input/output, backtracking, ...) returning values: they do not solve any input/output-problems directly but rather provide an elegant and flexible abstraction of many solutions to related problems.

What is maybe monad?

The Maybe monad represents computations which might "go wrong" by not returning a value.

What is either monad?

In Error handling we have two possible paths either a computation succeeds or fails. The imperative way to control the flow is using exceptions and a try/catch block.

Is either a monad Haskell?

Strictly speaking, Either cannot be a monad, as it has kind Type -> Type -> Type ; Either String can be (and is), because it has kind Type -> Type .


1 Answers

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).

like image 131
phipsgabler Avatar answered Sep 22 '22 15:09

phipsgabler