模板-haskell中的单双引号/撇号有啥区别?

Posted

技术标签:

【中文标题】模板-haskell中的单双引号/撇号有啥区别?【英文标题】:What is the difference between single double qoute/apostrophe in template-haskell?模板-haskell中的单双引号/撇号有什么区别? 【发布时间】:2021-11-18 19:05:56 【问题描述】:

在使用 Optics 包了解 Haskell 镜头时,我遇到了以下示例:

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

makeLenses ''Person
makePrisms 'Person

Name 类型的值代表什么?单引号和双引号之间有什么区别?

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

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.

【问题讨论】:

【参考方案1】:

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

考虑这个变体:

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

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

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

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

请注意,在实践中,习惯上为两个构造函数使用相同的名称,因此在实际代码中经常需要这种消歧。

【讨论】:

谢谢。我现在将引号理解为独特地创建类型和值构造函数的元表示。但是,我仍然不明白为什么我可以互换地传递类型和值名称:makeLenses ''PersonmakeLenses 'KPerson 似乎都可以工作。 @manews 这是一个很好的观点。在内部,我可以从源代码中看到makeLenses 调用reifyDatatype,其文档声明“此函数将接受使用 newtype 或 data 声明的类型的任何构造函数(值或类型)”。所以我想这使得两者都起作用。 hackage.haskell.org/package/th-abstraction-0.4.3.0/docs/… 看起来这样做是为了使 数据系列 工作——不是常见的情况。【参考方案2】:

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

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

makeLenses ''Person
makePrisms 'P

【讨论】:

以上是关于模板-haskell中的单双引号/撇号有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

数据库条件判断where 里面的单双引号用法。

jquery中的单双引号的试用问题

r Markdown的Yaml标头中的单引号和双引号有啥区别?

jsp 单双引号?

js单双引号之间的区别

python脚本入参的单、双引号