{-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE TypeFamilies #-} -- For type equality constraint. -- | -- Module: $HEADER$ -- Description: Magic class for OverloadedLabels. -- Copyright: (c) 2016, Peter Trško -- License: BSD3 -- -- Maintainer: peter.trsko@gmail.com -- Stability: experimental -- Portability: GHC specific language extensions. -- -- This module defines the `IsLabel` class which is used by the OverloadedLabels -- language extension. See the -- -- for more details. -- -- The key idea is that when GHC sees an occurrence of the new -- overloaded label syntax @#foo@, it is replaced with -- -- > fromLabel (proxy# :: Proxy# "foo") :: alpha -- -- plus a wanted constraint @IsLabel "foo" alpha@. -- -- On /GHC >=8.0.1/ we just reexport "GHC.OverloadedLabels" module. module Data.OverloadedLabels ( -- * Oveloaded Labels #ifdef HAVE_OVERLOADED_LABELS module GHC.OverloadedLabels #else IsLabel(..) #endif , Label(..) , getLabel , showLabel , unLabel ) where import Data.Function ((.), id) import Data.String (String) import Data.Typeable (Typeable) import GHC.TypeLits ( KnownSymbol , Symbol #if MIN_VERSION_base(4,8,0) , symbolVal' #else , symbolVal #endif ) import GHC.Exts (Proxy#) import Text.Show (Show(show, showsPrec), showChar, showString) #ifdef HAVE_OVERLOADED_LABELS import GHC.OverloadedLabels #else class IsLabel (l :: Symbol) a where fromLabel :: Proxy# l -> a #endif -- | -- /Since 0.4.2.0/ data Label (l :: Symbol) = Label (Proxy# l) deriving Typeable -- | -- /Since 0.4.2.0/ instance KnownSymbol l => Show (Label l) where showsPrec _ l = showChar '#' . showString (showLabel' l) where #if MIN_VERSION_base(4,8,0) showLabel' (Label p) = symbolVal' p #else showLabel' = symbolVal #endif -- | -- /Since 0.4.2.0/ instance (l1 ~ l2) => IsLabel l1 (Label l2) where fromLabel = Label -- | Type restricted version of 'show'. -- -- >>> showLabel #foo -- #foo -- -- /Since 0.4.2.0/ showLabel :: KnownSymbol l => Label l -> String showLabel = show -- | Type restricted identity function. -- -- /Since 0.4.2.0/ getLabel :: Label l -> Label l getLabel = id -- | Same as 'fromLabel', but works for 'Label' data type. -- -- /Since 0.4.2.0/ unLabel :: IsLabel l a => Label l -> a unLabel (Label proxy) = fromLabel proxy