【问题标题】:Exposing PureScript types to JavaScript向 JavaScript 公开 PureScript 类型
【发布时间】:2019-12-26 22:45:50
【问题描述】:

我可以在 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?)?

【问题讨论】:

  • 这是关于在运行时获得 PS 类型信息吗?我对 PS 一无所知,但我认为 PS 类型在编译时会被删除。
  • 这闻起来像,“我想做我习惯做的事情,在我正在学习的新模型中。”告诉我们您要解决什么问题,并且可能有一种 Haskell 式的解决方法。
  • 库必须公开 JS 类(即带有原型的函数),并且库函数返回的对象必须是这些类的实例。为了让事情变得更有趣,这些对象必须有方法。我想我会尝试在 JS 中创建一些助手并通过 FFI 调用它们。如果结果很糟糕,我会继续使用 TypeScript。

标签: haskell purescript


【解决方案1】:

一般来说,答案是“不”。运行时表示实际上取决于确切的类型。

对于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"]

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


最后,我还可以告诉您,Elm、Haskell 和 Idris 都不会展示您所追求的财产。运行时类型信息在 ML 世界中通常不是很重要的东西。有人可以说它在 Idris 中以某种方式有效地存在,但不是您所期望的方式。

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

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

【讨论】:

  • “PureScript 根本不对运行时表示做出任何承诺”作为从事 PureScript 工作的人,我不同意这一点。 PureScript 的部分意义在于拥有简单的规则来获取运行时表示。我会在数据构造函数上完全使用 instanceof,我对此没有任何问题。我不认为它是一个实现细节,我认为它是 PureScript 的核心部分。
猜你喜欢
  • 2014-12-11
  • 1970-01-01
  • 1970-01-01
  • 2015-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-01
  • 2013-03-18
相关资源
最近更新 更多