"foreign import data Foo :: Type" 和 "data Foo" 之间的区别

Difference between "foreign import data Foo :: Type" and just "data Foo"

在定义外来类型时,名义上的方法之间有什么功能上的区别吗? foreign import data Foo :: Type 方法使意图更清晰,但真的是这样吗?

虽然它们表面上看起来很相似,但它们在元语言中的表示方式却大不相同,因为它们在解析后会产生不同的构造(后者为ExternDataDeclaration for the former, DataDeclaration)。

例如,您可以派生数据声明的实例,但对外部数据声明这样做会引发错误。

-- This works
data Empty
derive instance eqEmpty :: Eq Empty
derive instance ordEmpty :: Ord Empty

-- This breaks
foreign import data Empty :: Type
derive instance eqEmpty :: Eq Empty

Error found:

  Cannot derive a type class instance, because the type declaration for Empty could not be found.

如果是国外的情况,就得自己写这些实例了。

我是 PureScript 的新手,所以我不知道是否还有其他限制会影响一个而不影响另一个。我会说出于所有实际目的,它们是相同的。

理论上这两个声明具有不同的含义:data X 没有居民(因此相当于 Void)但 import foreign data X :: Type 有未知居民。

目前这两种方式都无关紧要,但是 in the future 它可以为空的 data 类型编写一个空的 case 表达式。