I have a class that can be created from several arguments in Haskell which requires some complex validation of those arguments. Currently I have something like
makeAThingExcept :: String -> String -> ... String -> Except ThingError AThing
makeAThingExcept s1 s2 ... = do
unless (s1CheckPasses s1) (throwError (BadS1 s1))
...
data ThingError = BadS1 String ...
instance Show ThingError where
show (BadS1 s) = "Bad S1: " ++ s
makeAThing :: String -> String -> ... String -> AThing
makeAThing s1 s2 ... = case runExcept (makeAThingExcept s1 s2 ...) of
Right thing -> thing
Left err -> error (show err)
Setting aside whether there is a better way to do this by using more specific types than String
as arguments to makeAThingExcept
, is there a reason to prefer Except
over Either
in a case like this? What are the differences here between the capabilities and idiom of Except
vs Either
?
Except
; you can convert betweenExcept
andEither
usingexcept
andrunExcept
. – GlynnisExcept
vsEither
depending on context. – ChaineyAThing
is really essential, and entering valid args can be a bit tricky. So failure from user input (e.g. from a typo) can be common; but in code, something would have had to go quite wrong with whatever was generating the arguments: code that supplied bad arguments would be doing a bad job of makingAThing
s. – ChaineyAThing
s correctly). – ChaineyExceptT
was introduced to provide a type that was semantically devoted to error handling, as opposed toEither
which is the generic way to define sum types, only one application of which is to provide error-handling semantics. – Glynnisexcept
(or for that materExceptT
as a constructor). I can't seem to make anExcept
from anEither
. – Chainey