【问题标题】:How do the native JavaScript types get written in Elm?原生 JavaScript 类型是如何用 Elm 编写的?
【发布时间】:2016-06-27 22:15:56
【问题描述】:

如何在 Elm 中编写原生 JavaScript 类型?定义List 的文件出奇地简短易读:

我很好奇 Elm 如何证明 JavaScript 的类型安全接口。 JavaScript 是手工编写的,还是从 Haskell 等其他语言编译而来的?


Elm 的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

这告诉我们headtail可以在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
};

}();

我对@9​​87654333@这一行特别好奇,因为ctor这个词是functor这个词的后半部分——这可能意味着一个functor是用JavaScript编写的.


这些考虑因素很重要,因为我正在考虑编写 Tree a 和/或 QuadTree a 类型,从 Elm 内部编写(例如使用 Records)或编写供个人使用的模块可能会很好。

  • 树的一种实现可能只有节点
  • 另一个可以区分between 节点
  • 另一个只有 4 个无法区分的节点。

另一个例子可能是CircularList,但我现在只想专注于树木。

【问题讨论】:

    标签: javascript tree functor elm algebraic-data-types


    【解决方案1】:

    认为 ctor 是“构造函数”的缩写,List 只是作为链表实现的。每个节点要么是空列表 ({ ctor: '[]' }),要么由一个值 (_0) 和列表的其余部分 (_1) 与 '::' 构造函数组合而成。

    例如,[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;
    }
    

    【讨论】:

    • 长度为 1000 的链表会非常嵌套。除非他们使用指针
    • 我认为大型列表没有任何优化。 Array 类型应该具有更高的性能,甚至有人提议将默认集合从 List 切换到 Array 引用性能作为 #1 原因 github.com/elm-lang/elm-plans/issues/13
    • 哦,哇,在不可变和快速之间有权衡吗? elm-lang.org/blog/announce/0.12.1Elm 是一个非常正在进行中的工作,我还是很喜欢它
    【解决方案2】:

    我的预感是 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'};
    

    因此,我看不出有任何理由说明您提出的 TreeQuadTree 类型会因使用原生 javascript 模块编写而受益。我建议用 Elm 编写它们。

    【讨论】:

    猜你喜欢
    • 2018-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-06
    • 1970-01-01
    • 2017-01-04
    • 2010-10-08
    相关资源
    最近更新 更多