新类型与外国进口数据
newtype vs foreign import data
选择这些选项的实际原因是什么?
例如:
foreign import data Foo :: Type -> Type
newtype Foo a = Foo a
让我们假设在这两种情况下,我们通过一些函数得到一个 Foo:
foreign import newFoo :: forall a. a -> Foo a
区别在于 newtype
的数据表示是已知的,而 foreign import
则不是。
这样做的一个结果是,使用 newtype
,您可以通过模式匹配从 Foo a
中得到 a
:
let foo = newFoo 42
let (Foo fourtyTwo) = foo
并且 foreign import
你不能那样做。
另一个结果是 foreign import
函数 newFoo
可以自由选择表示,它不一定要等同于 a
,例如:
// JavaScript
exports.newFoo = function (a) { return { wrapped: a } }
但是 newtype
必须正好是 a
:
// JavaScript
exports.newFoo = function (a) { return a }
然后还有自动推导Newtype
class的便利,这开启了一些自动化的可能性。
回复评论中的第二个问题(以后请post单独提问):
如果您的 Foo
没有类型参数,但定义如下:
// Case 1
data Foo = Foo
// Case 2
foreign import data Foo :: Type
foreign import newFoo :: Foo
此处的区别与上面相同:对于 data
表示是已知的,对于 foreign import
则不是。
它在实践中的表现方式实际上取决于您的背景。我能想到的一个例子是 Eq
、Show
、Generic
等的自动推导,对于 foreign import
方法需要手动编码。想到的另一个例子是 data Foo
静态保证只有一个值,而 newFoo
可以在每次调用中自由 return 不同的值。
选择这些选项的实际原因是什么?
例如:
foreign import data Foo :: Type -> Type
newtype Foo a = Foo a
让我们假设在这两种情况下,我们通过一些函数得到一个 Foo:
foreign import newFoo :: forall a. a -> Foo a
区别在于 newtype
的数据表示是已知的,而 foreign import
则不是。
这样做的一个结果是,使用 newtype
,您可以通过模式匹配从 Foo a
中得到 a
:
let foo = newFoo 42
let (Foo fourtyTwo) = foo
并且 foreign import
你不能那样做。
另一个结果是 foreign import
函数 newFoo
可以自由选择表示,它不一定要等同于 a
,例如:
// JavaScript
exports.newFoo = function (a) { return { wrapped: a } }
但是 newtype
必须正好是 a
:
// JavaScript
exports.newFoo = function (a) { return a }
然后还有自动推导Newtype
class的便利,这开启了一些自动化的可能性。
回复评论中的第二个问题(以后请post单独提问):
如果您的 Foo
没有类型参数,但定义如下:
// Case 1
data Foo = Foo
// Case 2
foreign import data Foo :: Type
foreign import newFoo :: Foo
此处的区别与上面相同:对于 data
表示是已知的,对于 foreign import
则不是。
它在实践中的表现方式实际上取决于您的背景。我能想到的一个例子是 Eq
、Show
、Generic
等的自动推导,对于 foreign import
方法需要手动编码。想到的另一个例子是 data Foo
静态保证只有一个值,而 newFoo
可以在每次调用中自由 return 不同的值。