module Data.Coerce.Util
(
(#.)
, (.#)
, Binary
, CoerceBinary
, WrapBinary
, WrappedBinary
, showsNewtype
, readsNewtype
) where
import Data.Coerce
import Text.Read
import Text.Read.Lex
showsNewtype
:: Coercible b a
=> String
-> String
-> (Int -> a -> ShowS)
-> ([a] -> ShowS)
-> Int
-> b
-> ShowS
showsNewtype cons acc = s
where
s sp _ n x =
showParen (n > 10)
$ showString cons
. showString " {"
. showString acc
. showString " = "
. sp 0 (coerce x)
. showChar '}'
{-# INLINE showsNewtype #-}
readsNewtype
:: Coercible a b
=> String
-> String
-> (Int -> ReadS a)
-> ReadS [a]
-> Int
-> ReadS b
readsNewtype cons acc = r
where
r rp _ = readPrec_to_S $ parens $ prec 10 $ do
lift $ expect (Ident cons)
Punc "{" <- lexP
lift $ expect (Ident acc)
Punc "=" <- lexP
x <- reset (readS_to_Prec rp)
Punc "}" <- lexP
pure (coerce x)
{-# INLINE readsNewtype #-}
type Binary a = a -> a -> a
type CoerceBinary a b = Binary a -> Binary b
type WrapBinary f a = Binary a -> WrappedBinary f a
type WrappedBinary f a = Binary (f a)
infixr 9 #.
(#.) :: Coercible b c => (b -> c) -> (a -> b) -> a -> c
(#.) _ = coerce
{-# INLINE (#.) #-}
infixr 9 .#
(.#) :: Coercible a b => (b -> c) -> (a -> b) -> a -> c
(.#) f _ = coerce f
{-# INLINE (.#) #-}