What is the difference between single double qoute/apostrophe in template-haskell?

163 views Asked by At

When learning about Haskell lenses with the Optics package, i encountered the following example:

data Person = Person 
 { _name :: String
 , _age  :: Int
 } 

makeLenses ''Person
makePrisms 'Person

What does a value of type Name represent and what is the difference between that single and double single qoute/apostrophe?

Both seem to have the same type:

makeLenses, makePrisms :: Name -> DecsQ

The template-haskell documentation is incomprehensible to me. It focuses on syntax and lacks examples:

* 'f has type Name, and names the function f. Similarly 'C has type Name and names the data constructor C. In general '⟨thing⟩ interprets ⟨thing⟩ in an expression context.

* ''T has type Name, and names the type constructor T. That is, ''⟨thing⟩ interprets ⟨thing⟩ in a type context.

2

There are 2 answers

2
chi On BEST ANSWER

We have two forms of quoting to distinguish between the data constructor and the type constructor.

Consider this variant:

 data Person = KPerson 
    { _name :: String
    , _age  :: Int
    } 

makeLenses ''Person   -- the type constructor
makePrisms 'KPerson   -- the data constructor

Here it is clear that in one case we use a Name for the type constructor while in the other case we refer to a Name for the data constructor.

In principle, Haskell could have used a single form of quoting, provided that the names of constructors such as Person and KPerson are always kept distinct. Since this is not the case, we need to disambiguate between naming the type and data constructors.

Note that, in practice, it is customary to use the same name for both constructors, so this disambiguation is often needed in actual code.

0
Noughtmare On

Type constructors and term constructors can have the same name in Haskell, so you use double and single ticks, respectively, to indicate the difference. Here is that example from Optics with distinct names:

data Person = P 
 { _name :: String
 , _age  :: Int
 } 

makeLenses ''Person
makePrisms 'P