本机 JavaScript 类型如何用 Elm 编写?
How do the native JavaScript types get written in Elm?
原生 JavaScript 类型是如何用 Elm 编写的?定义 List
的文件非常短且易于阅读:
我很好奇 Elm 如何为 JavaScript 证明一个类型安全的接口。 JavaScript 是手写的,还是从其他语言编译而来的 Haskell?
榆树的List
类型
Elm 的关键线好像是...
module List exposing
( isEmpty, length, reverse, member
, head, tail, filter, take, drop
, repeat, (::), append, concat
)
import Basics exposing (..)
import Maybe
import Maybe exposing ( Maybe(Just,Nothing) )
import Native.List
(::) : a -> List a -> List a
(::) = Native.List.cons
infixr 5 ::
head : List a -> Maybe a
head list =
case list of
x :: xs ->
Just x
[] ->
Nothing
tail : List a -> Maybe (List a)
tail list =
case list of
x :: xs ->
Just xs
[] ->
Nothing
这告诉我们head
和tail
可以在Elm中定义,但是(::)
操作必须用JavaScript定义。以下是 JavaScript 中与构造函数有关的一些关键行:
var _elm_lang$core$Native_List = function() {
var Nil = { ctor: '[]' };
function Cons(hd, tl) { return { ctor: '::', _0: hd, _1: tl }; }
...
return {
Nil: Nil,
Cons: Cons,
// etc
};
}();
我对 { ctor: '::', _0: hd, _1: tl };
这行特别好奇,因为 ctor 这个词是 functor 这个词的后半部分 - - 这可能意味着函子写在 JavaScript.
这些考虑很重要,因为我正在考虑编写 Tree a
and/or QuadTree a
类型,从 Elm 内部编写(例如使用 Records)或编写一个供个人使用的模块。
- 一个树的实现可以只有节点
- 另一个可以区分between左和右节点
- 另一个只有 4 个无法区分的节点。
另一个示例可能是 CircularList
,但我现在只想关注树木。
我认为 ctor
是"constructor"的缩写,而List
只是作为链表实现的。每个节点要么是空列表({ ctor: '[]' }
),要么由一个值(在_0
)和列表的其余部分(在_1
)与[=17=放在一起]构造函数。
例如,列表 [1, 2]
将是 Cons(1, Cons(2, Nil))
,完全展开后将是
{ ctor: '::',
_0: 1,
_1: { ctor: '::',
_0: 2,
_1: { ctor: '[]' } } }
你可以在 toArray
函数中看到它正在使用 xs.ctor !== '[]'
检查它是否已经到达列表的末尾,或者它是否应该将头部推到数组并保持去。
function toArray(xs)
{
var out = [];
while (xs.ctor !== '[]')
{
out.push(xs._0);
xs = xs._1;
}
return out;
}
我的直觉是 List
的实现是用 Javascript 编写的,主要是因为它的构造函数是 []
和 ::
,但 Elm 不允许中缀运算符作为构造函数名称。
例如,我们在 Elm 中使用 List
的方式意味着定义实际上应该是这样的:
type List a = ([]) | (::) a (List a)
即使我们在这些构造函数上进行模式匹配,它也不会在 Elm 中编译,因此使用了使用 Javascript 定义实现的快捷方式。
如果您使用不同的名称编写自己的自定义列表实现,javascript 输出与 List
的 javascript 实现相同。
type MyList a = MyNil | MyCons a (MyList a)
...产量...
var _user$project$Temp1467112617033056$MyCons = F2(
function (a, b) {
return {ctor: 'MyCons', _0: a, _1: b};
});
var _user$project$Temp1467112617033056$MyNil = {ctor: 'MyNil'};
因此,我看不出有任何理由说明您提议的 Tree
或 QuadTree
类型会因在本机 javascript 模块中编写而受益。我建议用 Elm 编写它们。
原生 JavaScript 类型是如何用 Elm 编写的?定义 List
的文件非常短且易于阅读:
我很好奇 Elm 如何为 JavaScript 证明一个类型安全的接口。 JavaScript 是手写的,还是从其他语言编译而来的 Haskell?
榆树的List
类型
Elm 的关键线好像是...
module List exposing
( isEmpty, length, reverse, member
, head, tail, filter, take, drop
, repeat, (::), append, concat
)
import Basics exposing (..)
import Maybe
import Maybe exposing ( Maybe(Just,Nothing) )
import Native.List
(::) : a -> List a -> List a
(::) = Native.List.cons
infixr 5 ::
head : List a -> Maybe a
head list =
case list of
x :: xs ->
Just x
[] ->
Nothing
tail : List a -> Maybe (List a)
tail list =
case list of
x :: xs ->
Just xs
[] ->
Nothing
这告诉我们head
和tail
可以在Elm中定义,但是(::)
操作必须用JavaScript定义。以下是 JavaScript 中与构造函数有关的一些关键行:
var _elm_lang$core$Native_List = function() {
var Nil = { ctor: '[]' };
function Cons(hd, tl) { return { ctor: '::', _0: hd, _1: tl }; }
...
return {
Nil: Nil,
Cons: Cons,
// etc
};
}();
我对 { ctor: '::', _0: hd, _1: tl };
这行特别好奇,因为 ctor 这个词是 functor 这个词的后半部分 - - 这可能意味着函子写在 JavaScript.
这些考虑很重要,因为我正在考虑编写 Tree a
and/or QuadTree a
类型,从 Elm 内部编写(例如使用 Records)或编写一个供个人使用的模块。
- 一个树的实现可以只有节点
- 另一个可以区分between左和右节点
- 另一个只有 4 个无法区分的节点。
另一个示例可能是 CircularList
,但我现在只想关注树木。
我认为 ctor
是"constructor"的缩写,而List
只是作为链表实现的。每个节点要么是空列表({ ctor: '[]' }
),要么由一个值(在_0
)和列表的其余部分(在_1
)与[=17=放在一起]构造函数。
例如,列表 [1, 2]
将是 Cons(1, Cons(2, Nil))
,完全展开后将是
{ ctor: '::',
_0: 1,
_1: { ctor: '::',
_0: 2,
_1: { ctor: '[]' } } }
你可以在 toArray
函数中看到它正在使用 xs.ctor !== '[]'
检查它是否已经到达列表的末尾,或者它是否应该将头部推到数组并保持去。
function toArray(xs)
{
var out = [];
while (xs.ctor !== '[]')
{
out.push(xs._0);
xs = xs._1;
}
return out;
}
我的直觉是 List
的实现是用 Javascript 编写的,主要是因为它的构造函数是 []
和 ::
,但 Elm 不允许中缀运算符作为构造函数名称。
例如,我们在 Elm 中使用 List
的方式意味着定义实际上应该是这样的:
type List a = ([]) | (::) a (List a)
即使我们在这些构造函数上进行模式匹配,它也不会在 Elm 中编译,因此使用了使用 Javascript 定义实现的快捷方式。
如果您使用不同的名称编写自己的自定义列表实现,javascript 输出与 List
的 javascript 实现相同。
type MyList a = MyNil | MyCons a (MyList a)
...产量...
var _user$project$Temp1467112617033056$MyCons = F2(
function (a, b) {
return {ctor: 'MyCons', _0: a, _1: b};
});
var _user$project$Temp1467112617033056$MyNil = {ctor: 'MyNil'};
因此,我看不出有任何理由说明您提议的 Tree
或 QuadTree
类型会因在本机 javascript 模块中编写而受益。我建议用 Elm 编写它们。