Created
December 15, 2022 07:50
-
-
Save Profpatsch/ff2a46bb4d99b2a2cfa3b109d7a6cf46 to your computer and use it in GitHub Desktop.
Labelled values in Haskell that are accessible with record dot syntax
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE DataKinds #-} | |
{-# LANGUAGE DerivingStrategies #-} | |
module Label | |
( Label, | |
label, | |
label', | |
) | |
where | |
import Data.Data (Proxy (..)) | |
import Data.Typeable (Typeable) | |
import GHC.Records (HasField (..)) | |
import GHC.TypeLits (Symbol) | |
-- | A labelled value. | |
-- | |
-- Use 'label'/'label'' to construct, | |
-- then use dot-syntax to get the inner value. | |
newtype Label (label :: Symbol) value = Label value | |
deriving stock (Show, Eq, Ord) | |
deriving newtype (Typeable) | |
-- | Attach a label to a value; should be used with a type application to name the label. | |
-- | |
-- @@ | |
-- let f = label @"foo" 'f'@ :: Label "foo" Char | |
-- in f.foo :: Char | |
-- @@ | |
-- | |
-- Use dot-syntax to get the labelled value. | |
label :: forall label value. value -> Label label value | |
label value = Label value | |
-- | Attach a label to a value; Pass it a proxy with the label name in the argument type. | |
-- This is intended for passing through the label value; | |
-- you can also use 'label'. | |
-- | |
-- | |
-- @@ | |
-- let f = label' (Proxy @"foo") 'f'@ :: Label "foo" Char | |
-- in f.foo :: Char | |
-- @@ | |
-- | |
-- Use dot-syntax to get the labelled value. | |
label' :: forall label value. (Proxy label) -> value -> Label label value | |
label' Proxy value = Label value | |
-- | Fetches the labelled value. | |
instance HasField label (Label label value) value where | |
getField :: (Label label value) -> value | |
getField (Label value) = value |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment