single double qoute/apostrophe in template-haskell 有什么区别?

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

在学习Haskell lens with the Optics package时,我遇到了下面的例子:

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

makeLenses ''Person
makePrisms 'Person

Name 类型的值代表什么,单单和双单的区别是什么qoute/apostrophe?

两者似乎具有相同的类型:

makeLenses, makePrisms :: Name -> DecsQ

template-haskell documentation 对我来说是无法理解的。它侧重于语法,缺少示例:

* '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.

类型构造函数和术语构造函数在 Haskell 中可以具有相同的名称,因此您分别使用双刻度和单刻度来表示区别。这是 Optics 中具有不同名称的示例:

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

makeLenses ''Person
makePrisms 'P

我们有两种引用形式来区分数据构造函数和类型构造函数。

考虑这个变体:

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

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

很明显,在一种情况下,我们使用 Name 作为类型构造函数,而在另一种情况下,我们使用 Name 作为数据构造函数。

原则上,Haskell 可以使用单一形式的引号,前提是 PersonKPerson 等构造函数的名称始终保持不同。由于情况并非如此,我们需要在命名类型和数据构造函数之间消除歧义。

请注意,在实践中,两个构造函数通常使用相同的名称,因此在实际代码中经常需要消除歧义。