Haskell 向JavaScript公开PureScript类型

Haskell 向JavaScript公开PureScript类型,haskell,purescript,Haskell,Purescript,我可以在JS中使用PureScript类型吗?例如: type SomeType = /*type declaration*/ func :: SomeType func = /*type construction*/ 然后在JS中执行如下操作: let a = module.func() a instanceof module.SomeType === true -- PureScript: data T = A Int | B x :: T x = A 42 // JS: func

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

type SomeType = /*type declaration*/

func :: SomeType
func = /*type construction*/
然后在JS中执行如下操作:

let a = module.func()
a instanceof module.SomeType === true
-- 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);
-- PureScript:
data T = A Int | B

x, y :: T
x = A 42
y = B

// JS:
var x = ["A", 42]
var y = ["B"]
如果没有,如果有任何哈斯凯尔语(Elm、GHCJS、Idris?)我可以做到吗?

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

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

let a = module.func()
a instanceof module.SomeType === true
-- 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);
-- PureScript:
data T = A Int | B

x, y :: T
x = A 42
y = B

// JS:
var x = ["A", 42]
var y = ["B"]
因此,从技术上讲,您可以使用
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可以做到这一点,因为它没有做出任何承诺。看到了吗

例如,我知道管道中某个地方有一个pull请求,它将
数据
表示转换为数组,如下所示:

let a = module.func()
a instanceof module.SomeType === true
-- 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);
-- 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中,但不是以你期望的方式

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


如果您可以进一步了解实际问题是什么,那么我(或其他人)或许可以建议一个替代解决方案。

这是关于在运行时获取PS类型信息的吗?我对PS一无所知,但我会假设PS类型在编译时会被删除。这闻起来像是“我想在我正在学习的新模型中做我习惯做的事情。”告诉我们您试图解决的问题,可能有一种Haskell-y的解决方法。库必须公开JS类(即带有原型的函数)库函数返回的对象必须是这些类的实例。为了让事情变得更有趣,这些对象必须有方法。我想我会尝试在JS中创建一些助手,并通过FFI调用它们。如果结局不好,我将继续使用TypeScript。“PureScript只是对运行时表示不做任何承诺”,作为一个从事PureScript工作的人,我不同意这一点。PureScript的一部分要点是使用简单的规则来访问运行时表示。我会在数据构造函数上完全使用instanceof,我对此没有问题。我不认为这是一个实现细节,我认为它是PurrScript的核心部分。