将 PureScript 类型暴露给 JavaScript

sza*_*kus 3 haskell purescript

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

type SomeType = /*type declaration*/

func :: SomeType
func = /*type construction*/
Run Code Online (Sandbox Code Playgroud)

然后在 JS 中做这样的事情:

let a = module.func()
a instanceof module.SomeType === true
Run Code Online (Sandbox Code Playgroud)

如果没有,是否有任何 Haskellish 语言可以实现它(Elm、GHCJS、Idris?)?

Fyo*_*kin 7

一般来说,答案是“不”。运行时表示实际上取决于类型到底是什么。

对于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);
Run Code Online (Sandbox Code Playgroud)

所以你可以在技术上使用instanceof区分大小写,但不能确定类型本身。

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

-- PureScript:
newtype T = T Int

x :: T
x = T 42

// JS:
var x = 42;
Run Code Online (Sandbox Code Playgroud)

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

-- PureScript
type T = Int

x :: T
x = 42

// JS:
var x = 42;
Run Code Online (Sandbox Code Playgroud)

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

-- PureScript
type R = { x :: Int, y :: String }

r :: R
r = { x: 42, y: "foo" }

// JS:
var r = { x: 42, y: "foo" }
Run Code Online (Sandbox Code Playgroud)

所以底线是:没有好的方法可以做到这一点。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"]
Run Code Online (Sandbox Code Playgroud)

如果这个拉取请求被接受,你的程序就会被破坏。


最后,我还可以告诉您,Elm、Haskell 和 Idris 都不会展示您所追求的财产。运行时类型信息通常不是机器学习领域中的重要内容。有人可能会争辩说,它以某种方式有效地存在于 Idris 中,但不是以您期望的方式。

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

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

  • 作为从事 PureScript 工作的人,“PureScript 根本不对运行时表示做出任何承诺”,我不同意这一点。PureScript 的部分要点是拥有简单的规则来获取运行时演示。我完全会在数据构造函数上使用instanceof,对此我没有任何问题。我不认为它是一个实现细节,我认为它是 PureScript 的核心部分。 (3认同)