Template Haskell type quoting problems - haskell

The TemplateHaskell quoting documents two quotes ('') as the way to get the Name of a type:
> ''String
GHC.Base.String
This works fine for this type (name). However, I can't find a way to make it work nice for e.g. Maybe String:
> ''Maybe String -- interprets String as a data constructor
> ''Maybe ''String -- wants to apply ''String to the Name type
I know I can workaround via using [t| Maybe String |], but this is then in the Q monad, and requires type changes, and I think is not type-checked at the respective moment, only when spliced in.
I can also work around by first defining a type alias, type MaybeString = Maybe String, and then using ''MaybeString, but this is also cumbersome.
Any way to directly get what I want simply via the '' quotation?

'' is used to quote names, not types. Maybe is a name, Maybe String is not. It is therefore not too surprising that you have to give your type a name by defining a type alias, before you can quote that name.
[t| |] on the other hand, quotes types. Note the difference here.
Prelude> :t ''String
''String :: Language.Haskell.TH.Syntax.Name
Prelude> :t [t| String |]
[t| String |]
:: Language.Haskell.TH.Syntax.Q Language.Haskell.TH.Syntax.Type
So I'm afraid you cannot use '' for what you're trying to do.

I think what you're looking for is:
ConT ''Maybe `AppT` ConT ''String

Related

Is any Atom data type in Haskell?

When I read/show String I get/expect the result to be quoted. If I want to omit quotes, I can implement some type like:
newtype Atom = Atom String deriving (Eq, Ord)
instance Read Atom where ...
instance Show Atom where ...
But my question is: does such type already exist somewhere in libraries, in the base, may be? I just found some Data.Atom but seems it something different (XML, etc).
No. If you find yourself wanting this, it means you're using Show in an unintended way. The idea of show is that is should always yield valid Haskell code. The Show String instance guarantees this, by safely quoting and escaping the contents. Short of that, you would of course in general not get Haskell code. Now, sure there are applications where you want to display something and don't care about whether it's Haskell code, but that shouldn't be show then.
Usually, if you have a string anyway, you should just use putStrLn directly.
Since Read and Show are for converting data to/from strings, you can just use the id function :)
But seriously, a String is already the output of its own read or show, if you don't want it quoted.
Say, for example, to print any other value (or a String, if you want it to appear quoted), you do:
putStrLn (show "Hello") -- prints "Hello", with quotes.
whereas, to print a string unquoted, you can simply do:
putStrLn "Hello" -- prints Hello, unquoted.
Because of this, I don't think there is any utility for this (it is trivial, after all); in fact, your Atom instances would simply be:
instance Read Atom where read = Atom
instance Show Atom where show (Atom s) = s
Depending on what you're doing, you may want to inspect the type and use print for non-strings and putStrLn for strings like this:
import Data.Typeable
printAny :: (Show a, Typeable a) => a -> IO ()
printAny a = case cast a of
Just str -> putStrLn str
Nothing -> print a
Then, as desired:
*Main> printAny "no quotes"
no quotes
*Main> printAny (10 :: Int)
10

How does OverloadedStrings language extension work?

I am trying to understand the language extension OverloadedStrings from the page https://ocharles.org.uk/posts/2014-12-17-overloaded-strings.html.
When the OverloadedStrings is enabled, then String becomes a type Data.String.IsString a => a:
Prelude Data.String> :t fromString "Foo"
fromString "Foo" :: IsString a => a
In the description, the author has mentioned the following:
By enabling this extension, string literals are now a call to the
fromString function, which belongs to the IsString type class.
What does string literals are now a call to the fromString function ?
and also the author has mentioned:
This polymorphism is extremely powerful, and it allows us to write
embedded domain specific languages in Haskell source code, without
having to introduce new constructs for otherwise normal values.
what does without having to introduce new constructs for otherwise normal values mean?
When the OverloadedStrings is enabled, then String becomes a type Data.String.IsString a => a
No that is incorrect. A String remains a String. It has only effect on string literals, not variables that have as type a String, and these still can be Strings.
What does string literals are now a call to the fromString function?
It means that if you write a string literal, like "foo", Haskell implicitly writes fromString "foo", and thus you can use this like any IsString object.
what does without having to introduce new constructs for otherwise normal values mean?
It means that we can make our own types for which we can write some sort of "mini-parser", and thus write these objects as string literals in our code. For example if we make a datatype like:
newtype BoolList = BoolList [Bool] deriving Show
then we can write our own parser
instance IsString BoolList where
fromString = BoolList . map toBool
where toBool '1' = True
toBool _ = False
Now we can for example define a list of Bools as:
myboollist :: BoolList
myboollist = "10110010001"
So then we get:
Prelude Data.String> myboollist
BoolList [True,False,True,True,False,False,True,False,False,False,True]
We here thus wrote a string literal "10110010001", and that means that implictly, we wrote fromString "10110010001". Since the type of myboollist is BoolList, it is here clear to what the string literal is parsed.
This thus can be useful if some data types are complex, our would take a lot of code to construct an object.
Since the fromString call is however postponed, and frequently not all possible strings map to a value of the type (here it is the case, although it is debatable if it is good to just fill in False for everything else than '1'), it thus can raise errors at runtime when the string turns out to be "unparsable".
what does without having to introduce new constructs for otherwise normal values mean?
The next sentence says
So why should string literals be any different?
so this one refers primarily to number literals. Consider e.g. a type defining polynomials. Because + and * can only be applied to arguments of the same type, if we want
2*x^3 + 3*x :: Poly Int
to be legal, 2 and 3 have to be of type Poly Int; otherwise you'd need either
a separate operator to multiply a polynomial by a number: 2.*x^3 + 3.^x.
a constructor for a constant polynomial: (C 2)*x^3 + (C 3)*x
An example for string literals is given at the end:
However, SQL queries are notorious for injection attacks when we concatenate strings. Interestingly, postgresql-simple provides a Query type that only has a IsString instance. This means that it’s very lightweight to write a literal query, but the moment we want to start concatenating strings for our query, we have to be very explicit.

Tagging a string with corresponding symbol

I would like an easy way to create a String tagged with itself. 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 this is not nice because
The guarantee about the tag is only provided by tag not by the GADT.
Every time I want to create a value I have to provide a type signature, which
gets unwieldy if the value is part of some bigger expression.
Is there any way to improve this, preferably going in the opposite direction, i.e. from String to Symbol? I would like to write Tag "blah" and have ghc infer the type
TagString "blah".
GHC.TypeLits provides the someSymbolVal function which looks somewhat
related but it produces a SomeSymbol, not a Symbol and I can quite grasp how to use
it.
Is there any way to improve this, preferably going in the opposite direction, i.e. from String to Symbol?
There is no way to go directly from String to Symbol, because Haskell isn't dependently typed, unfortunately. You do have to write out a type annotation every time you want a new value and there isn't an existing tag with the desired symbol already around.
The guarantee about the tag is only provided by tag not by the GADT.
The following should work well (in fact, the same type can be found in the singletons package):
data SSym :: Symbol -> * where
SSym :: KnownSymbol s => SSym s
-- defining values
sym1 = SSym :: SSym "foo"
sym2 = SSym :: SSym "bar"
This type essentially differs from Proxy only by having the KnownSymbol dictionary in the constructor. The dictionary lets us recover the string contained within even if the symbol is not known statically:
extractString :: SSym s -> String
extractString s#SSym = symbolVal s
We pattern matched on SSym, thereby bringing into scope the implicit KnownSymbol dictionary. The same doesn't work with a mere Proxy:
extractString' :: forall (s :: Symbol). Proxy s -> String
extractString' p#Proxy = symbolVal p
-- type error, we can't recover the string from anywhere
... it produces a SomeSymbol, not a Symbol and I can quite grasp how to use it.
SomeSymbol is like SSym except it hides the string it carries around so that it doesn't appear in the type. The string can be recovered by pattern matching on the constructor.
extractString'' :: SomeSymbol -> String
extractString'' (SomeSymbol proxy) = symbolVal proxy
It can be useful when you want to manipulate different symbols in bulk, for example you can put them in a list (which you can't do with different SSym-s, because their types differ).

Why can't I use record selectors with an existentially quantified type?

When using Existential types, we have to use a pattern-matching syntax for extracting the foralled value. We can't use the ordinary record selectors as functions. GHC reports an error and suggest using pattern-matching with this definition of yALL:
{-# LANGUAGE ExistentialQuantification #-}
data ALL = forall a. Show a => ALL { theA :: a }
-- data ok
xALL :: ALL -> String
xALL (ALL a) = show a
-- pattern matching ok
-- ABOVE: heaven
-- BELOW: hell
yALL :: ALL -> String
yALL all = show $ theA all
-- record selector failed
forall.hs:11:19:
Cannot use record selector `theA' as a function due to escaped type variables
Probable fix: use pattern-matching syntax instead
In the second argument of `($)', namely `theA all'
In the expression: show $ theA all
In an equation for `yALL': yALL all = show $ theA all
Some of my data take more than 5 elements. It's hard to maintain the code if I
use pattern-matching:
func1 (BigData _ _ _ _ elemx _ _) = func2 elemx
Is there a good method to make code like that maintainable or to wrap it up so that I can use some kind of selectors?
Existential types work in a more elaborate manner than regular types. GHC is (rightly) forbidding you from using theA as a function. But imagine there was no such prohibition. What type would that function have? It would have to be something like this:
-- Not a real type signature!
theA :: ALL -> t -- for a fresh type t on each use of theA; t is an instance of Show
To put it very crudely, forall makes GHC "forget" the type of the constructor's arguments; all that the type system knows is that this type is an instance of Show. So when you try to extract the value of the constructor's argument, there is no way to recover the original type.
What GHC does, behind the scenes, is what the comment to the fake type signature above says—each time you pattern match against the ALL constructor, the variable bound to the constructor's value is assigned a unique type that's guaranteed to be different from every other type. Take for example this code:
case ALL "foo" of
ALL x -> show x
The variable x gets a unique type that is distinct from every other type in the program and cannot be matched with any type variable. These unique types are not allowed to escape to the top level—which is the reason why theA cannot be used as a function.
You can use record syntax in pattern matching,
func1 BigData{ someField = elemx } = func2 elemx
works and is much less typing for huge types.

Haskell. TagSoup library with OverloadedStrings

Good day, question is rather noobish, but i stuck with it.
I decided to migrate from plain Strings to Text in my project and faced the problem, all strings in source yielded compilation errors after adding {-# LANGUAGE OverloadedStrings #-}, for example snippet like:
dropWhile (~/= "<li>") tags
now leads to
Ambiguous type variable t' in the constraints:
Data.String.IsString t'
arising from the literal "<li>"'
at ParserOx.hs:93:42-47
TagRep t'
arising from a use of `~=='
What could be wrong here ?
UPD:
And yes, all my functions have signatures, ex:
getContainer :: [Tag Text] -> [Tag Text]
getContainer tags =
h
where
(h:t) = sections (~== "<div id=\"itemscontainer\">") tags
The problem is that you have an ambiguous type with two constraints -- the isstring constraint given by overloaded strings, and the tagrep constraint used by tagsoup to allow you to use tags or strings interchangeably. So two methods of "overloading" strings (one in general, and one just for use in tagsoup's matchers) are running into one another and causing confusion. Either turn off overloaded strings in the offending file, or specify your strings as actual strings in the code (i.e. (~/= ("<li>"::String))). Rather than inline type signatures, you can do the following to force types more quietly:
s :: String -> String
s = id
.... (~/= s "<li>") ...
One option is to define a wrapper around ~== which pins down parts of the type. For example, you could define:
(~===) a b = a ~== (b :: String)
Then you can just write (~=== "<div id=\"itemscontainer\">") with no further annotations at the use site.
The compiler can't find out what kind of String you want to have. Try to give your functions explicit signatures.

Resources