Mark a line with the corresponding character

I would like to create a simple tag Stringwith a tag. Right now I can do something like:

data TagString :: Symbol -> * where
    Tag :: String -> TagString s
    deriving Show

tag :: KnownSymbol s => Proxy s -> TagString s
tag s = Tag (symbolVal s)

and use it like

tag (Proxy :: Proxy "blah")

But it’s not nice because

  • The warranty on the tag is provided only by tagnon-GADT.
  • Every time I want to create a value, I have to provide a type signature that becomes cumbersome if the value is part of some larger expression.

Is there a way to improve this, it is preferable to go in the opposite direction, that is, from Stringto Symbol? I would like to write Tag "blah"and specify the ghc type TagString "blah".

GHC.TypeLits provides a function someSymbolValthat looks somewhat but it creates SomeSymbol, not Symbol, and I can quite understand how to use it.

+4
1

, , String to Symbol?

String Symbol, , , Haskell . , , .

, GADT.

(, singletons):

data SSym :: Symbol -> * where
    SSym :: KnownSymbol s => SSym s

-- defining values
sym1 = SSym :: SSym "foo"
sym2 = SSym :: SSym "bar"

Proxy KnownSymbol . , , :

extractString :: SSym s -> String
extractString s@SSym = symbolVal s 

SSym, KnownSymbol. Proxy:

extractString' :: forall (s :: Symbol). Proxy s -> String
extractString' p@Proxy = symbolVal p 
-- type error, we can't recover the string from anywhere

... SomeSymbol, , , .

SomeSymbol SSym, , , , . ​​ .

extractString'' :: SomeSymbol -> String
extractString'' (SomeSymbol proxy) = symbolVal proxy

, , , ( SSym -s, ).

+8

Source: https://habr.com/ru/post/1542701/


All Articles