将PureScript类型公开给JavaScript

问题描述 投票:0回答:1

我可以在JS中使用PureScript类型吗?例如:

type SomeType = /*type declaration*/

func :: SomeType
func = /*type construction*/

然后在JS中执行以下操作:

let a = module.func()
a instanceof module.SomeType === true

如果没有,我可以使用任何一种Haskellish语言(Elm,GHCJS,Idris?)?

haskell purescript
1个回答
5
投票
通常,答案为“否”。运行时表示形式实际上取决于确切的类型。

对于data声明,每个构造函数都将由一个JS“类”表示,如下所示:

-- PureScript: data T = A Int | B x :: T x = A 42 // JS: function A(value0) { this.value0 = value0; } A.create = function(value0) { return new A(value0); } function B() { } B.value = new B(); var x = A.create(42);

因此,从技术上讲,您可以使用instanceof区分大小写,但不能确定类型本身。

另一方面,对于newtype,类型包装器将被完全擦除,因为这是newtype的全部要点:

-- PureScript: newtype T = T Int x :: T x = T 42 // JS: var x = 42;

并且对于类型同义词(用type关键字声明),没有明显的表示形式。也就是说,此类类型在运行时的表示方式与其右侧表示相同:

-- PureScript type T = Int x :: T x = 42 // JS: var x = 42;

这也适用于裸记录,因为它们也只是类型同义词:

-- PureScript type R = { x :: Int, y :: String } r :: R r = { x: 42, y: "foo" } // JS: var r = { x: 42, y: "foo" }


所以最重要的是:没有很好的方法来做到这一点。 PureScript根本不对运行时表示作出任何保证。它对程序行为做出了很好的承诺,但对于JS(或您正巧使用的任何其他后端)如何实现它却不是。

这是另一个问题:

因为PureScript不会做出任何这样的承诺,所以依靠您(我的)对当前实现的知识是一个非常糟糕的主意,因为下一版编译器可能会更改它完全。 PureScript可以做到这一点,因为它没有承诺。看看如何运作?例如,我知道管线中的某个拉取请求会将data表示形式切换为数组,如下所示:

-- PureScript: data T = A Int | B x, y :: T x = A 42 y = B // JS: var x = ["A", 42] var y = ["B"]

如果此请求被接受,则您的程序将被破坏。


总之,我也可以告诉您,榆树,哈斯克尔或伊德里斯都不会展示您所追求的财产。在ML Universe中,运行时类型信息通常不是很重要的事情。可以说它以某种方式有效地存在于Idris中,但并非以您期望的方式存在。

您可能想要尝试F#/Fable:在这方面它要强一些,但仍不如其本机.NET运行时好。我不认为您可以从JS突然检查F#对象的类型,但是我知道Fable确实支持从F#本身访问RTTI(以额外的性能成本),因此您至少可以使函数做到这一点,并且将它们导出到JS。

如果您可以扩大实际问题的范围,那么也许我(或其他人)可以提出替代解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.