{-# LANGUAGE MagicHash #-}
{-# LANGUAGE RoleAnnotations #-}
{-# LANGUAGE ViewPatterns #-}
module Data.Label
( (:=)
( .., (:=) )
, Label
( Label )
) where
import Data.Kind
( Type )
import GHC.Exts
( proxy# )
import GHC.OverloadedLabels
( IsLabel
( fromLabel )
)
import GHC.TypeLits
( Symbol, KnownSymbol, symbolVal' )
data Label ( lbl :: Symbol ) = Label
type role Label nominal
instance ( lbl' ~ lbl ) => IsLabel lbl ( Label lbl' ) where
fromLabel :: Label lbl'
fromLabel = Label lbl'
forall (lbl :: Symbol). Label lbl
Label
instance KnownSymbol lbl => Show ( Label lbl ) where
show :: Label lbl -> String
show Label lbl
_ = String
"#" String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Proxy# lbl -> String
forall (n :: Symbol). KnownSymbol n => Proxy# n -> String
symbolVal' @lbl Proxy# lbl
forall k (a :: k). Proxy# a
proxy#
newtype ( lbl :: Symbol ) := ( a :: Type ) = Labelled { (lbl := a) -> a
unLabel :: a }
instance ( KnownSymbol lbl, Show a ) => Show ( lbl := a ) where
showsPrec :: Int -> (lbl := a) -> ShowS
showsPrec Int
p ( Labelled a
a ) =
Bool -> ShowS -> ShowS
showParen ( Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1 )
( String -> ShowS
showString ( Label lbl -> String
forall a. Show a => a -> String
show ( Label lbl
forall (lbl :: Symbol). Label lbl
Label @lbl ) String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" := " ) ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> a -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
2 a
a )
infix 1 :=
pattern (:=) :: Label lbl -> a -> lbl := a
pattern lbl $b:= :: Label lbl -> a -> lbl := a
$m:= :: forall r (lbl :: Symbol) a.
(lbl := a) -> (Label lbl -> a -> r) -> (Void# -> r) -> r
:= a <- ( ( \ ( Labelled a ) -> LabelPair Label a ) -> LabelPair lbl a )
where
Label lbl
_ := a
a = a -> lbl := a
forall (lbl :: Symbol) a. a -> lbl := a
Labelled a
a
{-# COMPLETE (:=) #-}
data LabelPair lbl a = LabelPair !( Label lbl ) !a