Safe Haskell  Trustworthy 

Language  Haskell2010 
A (slightly unsafe) term level implementation for Symbol
.
As Symbol
in base
doesn't have any termlevel operations,
it's sometimes necessary to have two copies of the same data,
the first one using String
on term level and
second one using Symbol
to be promtoed to type level.
In GHC9.2 the similar problem was fixed for Nat
and Natural
,
which were distinct types (kinds) before that.
As String
is a list of Char
s, we cannot make type
,
but we could do Symbol
= String
newtype
.
This module fakes that by using Symbol
= MkSymbol String
unsafeCoerce
under the hood.
Fleshing out Symbol
on term level is suggested in
https://gitlab.haskell.org/ghc/ghc//issues/10776#note_109601
in 2015.
This implementation is slightly unsafe, as currently Symbol
is defined
as empty data type:
data Symbol
This means that you can write
dangerous :: Symbol > Int dangerous x = case x of
and because GHC sees through everything, and knows that Symbol
is empty,
the above compiles without a warning.
If Symbol
was defined as newtype Symbol = Symbol Any
, the
above problem would go away, and also implementation of this
module would be safer, as unsafeCoerce
ing from lifted type to Any
and back is guaranteed to work.
Of course life would be easier if we just had
newtypeSymbol
= MkSymbolString
but until that is done, you may find this module useful.
Note: Symbol
is not Text
. Text
has an invariant: it represents valid Unicode text.
Symbol
is just a list of characters (= Unicode codepoints), like String
.
E.g.
>>>
"\55555" :: String
"\55555"
>>>
"\55555" :: Symbol
"\55555"
but text
replaces surrogate codepoints:
>>>
"\55555" :: Text
"\65533"
Symbol
could use some packed representation of list of characters,
if also KnownSymbol
would use it as well. Currently
KnownSymbol
dictionary carries a String
, so having
Symbol
be a String
is justified'.
Synopsis
 data Symbol
 symbolToString :: Symbol > String
 consSymbol :: Char > Symbol > Symbol
 unconsSymbol :: Symbol > Maybe (Char, Symbol)
 class KnownSymbol (n :: Symbol)
 symbolVal :: forall n proxy. KnownSymbol n => proxy n > Symbol
 symbolVal' :: forall n. KnownSymbol n => Proxy# n > Symbol
 type family AppendSymbol (a :: Symbol) (b :: Symbol) :: Symbol where ...
 type family CmpSymbol (a :: Symbol) (b :: Symbol) :: Ordering where ...
 someSymbolVal :: Symbol > SomeSymbol
 data SomeSymbol = KnownSymbol n => SomeSymbol (Proxy n)
 sameSymbol :: forall (a :: Symbol) (b :: Symbol). (KnownSymbol a, KnownSymbol b) => Proxy a > Proxy b > Maybe (a :~: b)
Symbol type
(Kind) This is the kind of typelevel symbols. Declared here because class IP needs it
Instances
IsList Symbol Source #  
Eq Symbol Source #  
Ord Symbol Source #  
Read Symbol Source #  
Show Symbol Source # 

IsString Symbol Source # 

Defined in GHC.Symbol fromString :: String > Symbol #  
Semigroup Symbol Source #  
Monoid Symbol Source #  
PrintfArg Symbol Source #  
Defined in GHC.Symbol formatArg :: Symbol > FieldFormatter # parseFormat :: Symbol > ModifierParser #  
Binary Symbol Source #  
NFData Symbol Source #  
Defined in GHC.Symbol  
SingKind Symbol  Since: base4.9.0.0 
Defined in GHC.Generics type DemoteRep Symbol  
Lift Symbol Source #  
KnownSymbol a => SingI (a :: Symbol)  Since: base4.9.0.0 
Defined in GHC.Generics sing :: Sing a  
type Item Symbol Source #  
Defined in GHC.Symbol  
type DemoteRep Symbol  
Defined in GHC.Generics  
data Sing (s :: Symbol)  
Defined in GHC.Generics 
symbolToString :: Symbol > String Source #
consSymbol :: Char > Symbol > Symbol Source #
Prepend a character to a Symbol
>>>
consSymbol 'a' "cute"
"acute"
Type level
class KnownSymbol (n :: Symbol) #
This class gives the string associated with a typelevel symbol. There are instances of the class for every concrete literal: "hello", etc.
Since: base4.7.0.0
symbolSing
symbolVal :: forall n proxy. KnownSymbol n => proxy n > Symbol Source #
>>>
symbolVal (Proxy @"foobar")
"foobar"
symbolVal' :: forall n. KnownSymbol n => Proxy# n > Symbol Source #
type family AppendSymbol (a :: Symbol) (b :: Symbol) :: Symbol where ... #
Concatenation of typelevel symbols.
Since: base4.10.0.0
type family CmpSymbol (a :: Symbol) (b :: Symbol) :: Ordering where ... #
Comparison of typelevel symbols, as a function.
Since: base4.7.0.0
someSymbolVal :: Symbol > SomeSymbol Source #
>>>
someSymbolVal "foobar"
"foobar"
data SomeSymbol #
This type represents unknown typelevel symbols.
KnownSymbol n => SomeSymbol (Proxy n)  Since: base4.7.0.0 
Instances
Eq SomeSymbol  Since: base4.7.0.0 
Defined in GHC.TypeLits (==) :: SomeSymbol > SomeSymbol > Bool # (/=) :: SomeSymbol > SomeSymbol > Bool #  
Ord SomeSymbol  Since: base4.7.0.0 
Defined in GHC.TypeLits compare :: SomeSymbol > SomeSymbol > Ordering # (<) :: SomeSymbol > SomeSymbol > Bool # (<=) :: SomeSymbol > SomeSymbol > Bool # (>) :: SomeSymbol > SomeSymbol > Bool # (>=) :: SomeSymbol > SomeSymbol > Bool # max :: SomeSymbol > SomeSymbol > SomeSymbol # min :: SomeSymbol > SomeSymbol > SomeSymbol #  
Read SomeSymbol  Since: base4.7.0.0 
Defined in GHC.TypeLits readsPrec :: Int > ReadS SomeSymbol # readList :: ReadS [SomeSymbol] # readPrec :: ReadPrec SomeSymbol # readListPrec :: ReadPrec [SomeSymbol] #  
Show SomeSymbol  Since: base4.7.0.0 
Defined in GHC.TypeLits showsPrec :: Int > SomeSymbol > ShowS # show :: SomeSymbol > String # showList :: [SomeSymbol] > ShowS # 
sameSymbol :: forall (a :: Symbol) (b :: Symbol). (KnownSymbol a, KnownSymbol b) => Proxy a > Proxy b > Maybe (a :~: b) #
We either get evidence that this function was instantiated with the
same typelevel symbols, or Nothing
.
Since: base4.7.0.0
Orphan instances
IsList Symbol Source #  
Eq Symbol Source #  
Ord Symbol Source #  
Read Symbol Source #  
Show Symbol Source # 

IsString Symbol Source # 

fromString :: String > Symbol #  
Semigroup Symbol Source #  
Monoid Symbol Source #  
PrintfArg Symbol Source #  
formatArg :: Symbol > FieldFormatter # parseFormat :: Symbol > ModifierParser #  
Binary Symbol Source #  
NFData Symbol Source #  
Lift Symbol Source #  