improve error interfaces
This commit is contained in:
parent
36b3479c8d
commit
cdcd926347
1 changed files with 43 additions and 50 deletions
|
@ -10,6 +10,8 @@ import Control.Monad.RWS
|
||||||
%default total
|
%default total
|
||||||
|
|
||||||
|
|
||||||
|
||| a proof that an element is in a list. unlike the standard library one, this
|
||||||
|
||| is represented as a single number at runtime.
|
||||||
public export
|
public export
|
||||||
data Elem : a -> List a -> Type where
|
data Elem : a -> List a -> Type where
|
||||||
Here : x `Elem` (x :: xs)
|
Here : x `Elem` (x :: xs)
|
||||||
|
@ -22,6 +24,8 @@ Uninhabited (x `Elem` []) where
|
||||||
uninhabited (There _) impossible
|
uninhabited (There _) impossible
|
||||||
|
|
||||||
|
|
||||||
|
||| a representation of a list's length. this is used in the `Ord` instance to
|
||||||
|
||| transform the `Ord` constraints into `Eq`s
|
||||||
public export
|
public export
|
||||||
data Spine : List a -> Type where
|
data Spine : List a -> Type where
|
||||||
NIL : Spine []
|
NIL : Spine []
|
||||||
|
@ -29,6 +33,8 @@ data Spine : List a -> Type where
|
||||||
%builtin Natural Spine
|
%builtin Natural Spine
|
||||||
|
|
||||||
|
|
||||||
|
||| if `types` is a `List Type`, then `OneOf types` is a value of one of them.
|
||||||
|
||| (along with a pointer to which type it is.)
|
||||||
public export
|
public export
|
||||||
record OneOf types where
|
record OneOf types where
|
||||||
constructor One
|
constructor One
|
||||||
|
@ -43,6 +49,7 @@ export %inline
|
||||||
inj : ty `Elem` tys => ty -> OneOf tys
|
inj : ty `Elem` tys => ty -> OneOf tys
|
||||||
inj value = One %search value
|
inj value = One %search value
|
||||||
|
|
||||||
|
||| `All p types` computes a constraint for `p a` for each `a` in `types`
|
||||||
public export
|
public export
|
||||||
All : (Type -> Type) -> List Type -> Type
|
All : (Type -> Type) -> List Type -> Type
|
||||||
All p [] = ()
|
All p [] = ()
|
||||||
|
@ -56,7 +63,7 @@ eq (One (There p) x) (One (There q) y) = eq (One p x) (One q y)
|
||||||
eq (One Here _) (One (There _) _) = False
|
eq (One Here _) (One (There _) _) = False
|
||||||
eq (One (There z) x) (One Here y) = False
|
eq (One (There z) x) (One Here y) = False
|
||||||
|
|
||||||
export
|
export %inline
|
||||||
All Eq types => Eq (OneOf types) where (==) = eq
|
All Eq types => Eq (OneOf types) where (==) = eq
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,7 +72,7 @@ ordsToEqs : Spine types => All Ord types => All Eq types
|
||||||
ordsToEqs @{NIL} = ()
|
ordsToEqs @{NIL} = ()
|
||||||
ordsToEqs @{CONS tl} = (%search, ordsToEqs @{tl})
|
ordsToEqs @{CONS tl} = (%search, ordsToEqs @{tl})
|
||||||
|
|
||||||
private
|
private %inline
|
||||||
[eqOrds] (Spine types, All Ord types) => Eq (OneOf types) where
|
[eqOrds] (Spine types, All Ord types) => Eq (OneOf types) where
|
||||||
(==) = eq @{ordsToEqs}
|
(==) = eq @{ordsToEqs}
|
||||||
|
|
||||||
|
@ -77,15 +84,16 @@ cmp (One Here _) (One (There _) _) = LT
|
||||||
cmp (One (There _) _) (One Here _) = GT
|
cmp (One (There _) _) (One Here _) = GT
|
||||||
cmp (One (There p) x) (One (There q) y) = cmp (One p x) (One q y)
|
cmp (One (There p) x) (One (There q) y) = cmp (One p x) (One q y)
|
||||||
|
|
||||||
export
|
export %inline
|
||||||
(Spine types, All Ord types) => Ord (OneOf types) using eqOrds where
|
(Spine types, All Ord types) => Ord (OneOf types) using eqOrds where
|
||||||
compare = cmp
|
compare = cmp
|
||||||
|
|
||||||
|
|
||||||
export
|
private shw : All Show types => Prec -> OneOf types -> String
|
||||||
All Show types => Show (OneOf types) where
|
shw d (One Here value) = showPrec d value
|
||||||
showPrec d (One Here value) = showPrec d value
|
shw d (One (There p) value) = shw d $ One p value
|
||||||
showPrec d (One (There p) value) = showPrec d $ One p value
|
|
||||||
|
export %inline All Show types => Show (OneOf types) where showPrec = shw
|
||||||
|
|
||||||
|
|
||||||
public export
|
public export
|
||||||
|
@ -173,43 +181,28 @@ MkErrorT act1 <|> MkErrorT act2 = MkErrorT [|act1 `or` act2|] where
|
||||||
|
|
||||||
|
|
||||||
public export
|
public export
|
||||||
interface Monad m => MonadThrow errs m | m where
|
interface Monad m => MonadThrow err m where
|
||||||
throw : err `Elem` errs => err -> m a
|
throw : err -> m a
|
||||||
|
|
||||||
public export
|
public export
|
||||||
interface
|
interface MonadThrow err m1 => MonadCatch err m1 m2 | err, m1 where
|
||||||
(MonadThrow errs1 m1,
|
|
||||||
MonadThrow errs2 m2,
|
|
||||||
err `Elem` errs1) =>
|
|
||||||
MonadCatch err errs1 errs2 m1 m2
|
|
||||||
| err, m1
|
|
||||||
where
|
|
||||||
catch : (act : m1 a) -> (catch : err -> m2 a) -> m2 a
|
catch : (act : m1 a) -> (catch : err -> m2 a) -> m2 a
|
||||||
|
|
||||||
public export
|
public export
|
||||||
interface
|
interface (Monad m1, Monad m2) => MonadEmbed m1 m2 where embed : m1 a -> m2 a
|
||||||
(MonadThrow errs1 m1,
|
|
||||||
MonadThrow errs2 m2,
|
|
||||||
Embed errs1 errs2) =>
|
|
||||||
MonadEmbed errs1 errs2 m1 m2
|
|
||||||
| m1, m2
|
|
||||||
where
|
|
||||||
embed : m1 a -> m2 a
|
|
||||||
|
|
||||||
|
|
||||||
export %inline
|
export %inline
|
||||||
implementation
|
implementation
|
||||||
Monad m =>
|
(Monad m, err `Elem` errs) =>
|
||||||
MonadThrow errs (ErrorT errs m)
|
MonadThrow err (ErrorT errs m)
|
||||||
where
|
where
|
||||||
throw = MkErrorT . pure . Left . inj
|
throw = MkErrorT . pure . Left . inj
|
||||||
|
|
||||||
export %inline
|
export %inline
|
||||||
implementation
|
implementation
|
||||||
(Monad m, err `Elem` errs) =>
|
(Monad m, err `Elem` errs) =>
|
||||||
MonadCatch err errs (errs `without` err)
|
MonadCatch err (ErrorT errs m) (ErrorT (errs `without` err) m)
|
||||||
(ErrorT errs m)
|
|
||||||
(ErrorT (errs `without` err) m)
|
|
||||||
where
|
where
|
||||||
catch (MkErrorT act) handler = MkErrorT $
|
catch (MkErrorT act) handler = MkErrorT $
|
||||||
act <&> mapFst (get err) >>= \case
|
act <&> mapFst (get err) >>= \case
|
||||||
|
@ -220,7 +213,7 @@ where
|
||||||
export %inline
|
export %inline
|
||||||
implementation
|
implementation
|
||||||
(Monad m, Embed errs1 errs2) =>
|
(Monad m, Embed errs1 errs2) =>
|
||||||
MonadEmbed errs1 errs2 (ErrorT errs1 m) (ErrorT errs2 m)
|
MonadEmbed (ErrorT errs1 m) (ErrorT errs2 m)
|
||||||
where
|
where
|
||||||
embed (MkErrorT act) = MkErrorT $ mapFst {elem $= embedElem} <$> act
|
embed (MkErrorT act) = MkErrorT $ mapFst {elem $= embedElem} <$> act
|
||||||
|
|
||||||
|
@ -261,46 +254,46 @@ HasIO m => HasIO (ErrorT errs m) where
|
||||||
|
|
||||||
|
|
||||||
export %inline
|
export %inline
|
||||||
MonadThrow errs m => MonadThrow errs (ReaderT r m) where throw = lift . throw
|
MonadThrow err m => MonadThrow err (ReaderT r m) where throw = lift . throw
|
||||||
|
|
||||||
export %inline
|
export %inline
|
||||||
MonadThrow errs m => MonadThrow errs (WriterT w m) where throw = lift . throw
|
MonadThrow err m => MonadThrow err (WriterT w m) where throw = lift . throw
|
||||||
|
|
||||||
export %inline
|
export %inline
|
||||||
MonadThrow errs m => MonadThrow errs (StateT s m) where throw = lift . throw
|
MonadThrow err m => MonadThrow err (StateT s m) where throw = lift . throw
|
||||||
|
|
||||||
export %inline
|
export %inline
|
||||||
MonadThrow errs m => MonadThrow errs (RWST r w s m) where throw = lift . throw
|
MonadThrow err m => MonadThrow err (RWST r w s m) where throw = lift . throw
|
||||||
|
|
||||||
|
|
||||||
export %inline
|
export %inline
|
||||||
implementation
|
implementation
|
||||||
MonadCatch err errs1 errs2 m1 m2 =>
|
MonadCatch err m1 m2 =>
|
||||||
MonadCatch err errs1 errs2 (ReaderT r m1) (ReaderT r m2)
|
MonadCatch err (ReaderT r m1) (ReaderT r m2)
|
||||||
where
|
where
|
||||||
catch (MkReaderT act) handler = MkReaderT $ \r =>
|
catch (MkReaderT act) handler = MkReaderT $ \r =>
|
||||||
act r `catch` runReaderT r . handler
|
act r `catch` runReaderT r . handler
|
||||||
|
|
||||||
export %inline
|
export %inline
|
||||||
implementation
|
implementation
|
||||||
MonadCatch err errs1 errs2 m1 m2 =>
|
MonadCatch err m1 m2 =>
|
||||||
MonadCatch err errs1 errs2 (WriterT w m1) (WriterT w m2)
|
MonadCatch err (WriterT w m1) (WriterT w m2)
|
||||||
where
|
where
|
||||||
catch (MkWriterT act) handler = MkWriterT $ \w =>
|
catch (MkWriterT act) handler = MkWriterT $ \w =>
|
||||||
act w `catch` \e => unWriterT (handler e) w
|
act w `catch` \e => unWriterT (handler e) w
|
||||||
|
|
||||||
export %inline
|
export %inline
|
||||||
implementation
|
implementation
|
||||||
MonadCatch err errs1 errs2 m1 m2 =>
|
MonadCatch err m1 m2 =>
|
||||||
MonadCatch err errs1 errs2 (StateT s m1) (StateT s m2)
|
MonadCatch err (StateT s m1) (StateT s m2)
|
||||||
where
|
where
|
||||||
catch (ST act) handler = ST $ \s =>
|
catch (ST act) handler = ST $ \s =>
|
||||||
act s `catch` \e => runStateT' (handler e) s
|
act s `catch` \e => runStateT' (handler e) s
|
||||||
|
|
||||||
export %inline
|
export %inline
|
||||||
implementation
|
implementation
|
||||||
MonadCatch err errs1 errs2 m1 m2 =>
|
MonadCatch err m1 m2 =>
|
||||||
MonadCatch err errs1 errs2 (RWST r w s m1) (RWST r w s m2)
|
MonadCatch err (RWST r w s m1) (RWST r w s m2)
|
||||||
where
|
where
|
||||||
catch (MkRWST act) handler = MkRWST $ \r, s, w =>
|
catch (MkRWST act) handler = MkRWST $ \r, s, w =>
|
||||||
act r s w `catch` \e => unRWST (handler e) r s w
|
act r s w `catch` \e => unRWST (handler e) r s w
|
||||||
|
@ -308,28 +301,28 @@ where
|
||||||
|
|
||||||
export %inline
|
export %inline
|
||||||
implementation
|
implementation
|
||||||
MonadEmbed errs1 errs2 m1 m2 =>
|
MonadEmbed m1 m2 =>
|
||||||
MonadEmbed errs1 errs2 (ReaderT r m1) (ReaderT r m2)
|
MonadEmbed (ReaderT r m1) (ReaderT r m2)
|
||||||
where
|
where
|
||||||
embed (MkReaderT act) = MkReaderT $ embed . act
|
embed (MkReaderT act) = MkReaderT $ embed . act
|
||||||
|
|
||||||
export %inline
|
export %inline
|
||||||
implementation
|
implementation
|
||||||
MonadEmbed errs1 errs2 m1 m2 =>
|
MonadEmbed m1 m2 =>
|
||||||
MonadEmbed errs1 errs2 (WriterT w m1) (WriterT w m2)
|
MonadEmbed (WriterT w m1) (WriterT w m2)
|
||||||
where
|
where
|
||||||
embed (MkWriterT act) = MkWriterT $ embed . act
|
embed (MkWriterT act) = MkWriterT $ embed . act
|
||||||
|
|
||||||
export %inline
|
export %inline
|
||||||
implementation
|
implementation
|
||||||
MonadEmbed errs1 errs2 m1 m2 =>
|
MonadEmbed m1 m2 =>
|
||||||
MonadEmbed errs1 errs2 (StateT s m1) (StateT s m2)
|
MonadEmbed (StateT s m1) (StateT s m2)
|
||||||
where
|
where
|
||||||
embed (ST act) = ST $ embed . act
|
embed (ST act) = ST $ embed . act
|
||||||
|
|
||||||
export %inline
|
export %inline
|
||||||
implementation
|
implementation
|
||||||
MonadEmbed errs1 errs2 m1 m2 =>
|
MonadEmbed m1 m2 =>
|
||||||
MonadEmbed errs1 errs2 (RWST r w s m1) (RWST r w s m2)
|
MonadEmbed (RWST r w s m1) (RWST r w s m2)
|
||||||
where
|
where
|
||||||
embed (MkRWST act) = MkRWST $ \r, s, w => embed $ act r s w
|
embed (MkRWST act) = MkRWST $ \r, s, w => embed $ act r s w
|
||||||
|
|
Loading…
Reference in a new issue