[GHC] #12160: MonadFail instance for (Either String)?
GHC
ghc-devs at haskell.org
Wed Jun 8 08:31:40 UTC 2016
#12160: MonadFail instance for (Either String)?
-------------------------------------+-------------------------------------
Reporter: lexi.lambda | Owner:
Type: feature request | Status: new
Priority: normal | Milestone:
Component: libraries | Version: 8.0.1
(other) |
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by Iceland_jack):
Do you have a use case? I don't think details of string conversion belong
in the `MonadError` instances and if you want instances like `MonadFail
(Either ByteString)` that brings up issues of encoding, truncation (as
`IsString ByteString`).
It would complicate the type class and make inference fail in basic
examples
{{{#!hs
data Foobar = Foo Int | Bar String
instance MonadFail (Either String) where
fail = Left
}}}
{{{
ghci> do Bar a <- Right (Foo 42)
ghci| pure a
ghci|
<interactive>:13:1: error:
• Ambiguous type variable ‘a0’ arising from a use of ‘print’
prevents the constraint ‘(Show a0)’ from being solved.
...
}}}
I argue most users would prefer
{{{#!hs
instance String ~ a => MonadFail (Either a) where
fail = Left
}}}
{{{
ghci> do Bar a <- Right (Foo 42)
ghci| pure a
ghci|
Left "Pattern match failure in do expression at <interactive>:11:4-8"
}}}
and if they want to avoid `String` entirely they can use `throwError` from
[https://hackage.haskell.org/package/mtl-2.2.1/docs/Control-Monad-
Except.html#t:MonadError MonadError] and be polymorphic in the error
{{{#!hs
throwError :: e -> Either e a
throwError @String @(Either _) :: String -> Either String a
throwError @Text @(Either _) :: Text -> Either Text a
throwError @[Bool] @(Either _) :: [Bool] -> Either [Bool] a
}}}
{{{#!hs
instance MonadError e (Either e) where
throwError :: e -> Either e a
throwError = Left
catchError :: Either e a -> (e -> Either e a) -> Either e a
Left l `catchError` h = h l
Right r `catchError` _ = Right r
}}}
----
This may be what you were aiming at,
{{{#!hs
instance IsString str => MonadFail (Either str) where
fail :: String -> Either str a
fail = Left . fromString
-- Left "Pattern match failure in do expression at /tmp/tH2v.hs:16:3-7"
str :: Either String String
str = do Bar a <- Right (Foo 42); pure a
-- Left "Pattern match failure in do expression at /tmp/tH2v.hs:21:3-7"
txt :: Either Text String
txt = do Bar a <- Right (Foo 42); pure a
-- Left (Const (Identity "Pattern match failure in do expression at
/tmp/tH2v.hs:26:3-7"))
cnst :: Either (Const (Identity [Char]) ()) String
cnst = do Bar a <- Right (Foo 42); pure a
}}}
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/12160#comment:5>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list