【问题标题】:SML consing a datatype list使用数据类型列表的 SML
【发布时间】:2020-07-22 20:57:19
【问题描述】:

如果我有这个 SML 数据类型

datatype json =
         Num of real
       | String of string
       | False
       | True
       | Null
       | Array of json list
       | Object of (string * json) list

假设我有这个Array,只有一个Object,这使它成为json 列表

Array[Object[("a", Num (1.0)),("b", True)]]

我怎样才能将新的Object 添加到现有的Array 上?我尝试了一个简单的:: 无济于事

Object[("a", Num (1.0)),("b", True)]::Array[Object[("a", Num (2.0)),("b", True)]]

给出一个错误。我必须为此建立自己的缺点吗?似乎 SML 列表是 'a list 应该允许 json list 并使用 ::

是的,这是我在华盛顿大学上一学期的编程语言的家庭作业,我正在自己做。 This 是分配。

我的基本问题是我不知道如何通过递归调用添加到Array。如果我需要生成一个包含ObjectsArray,并在每次递归调用时将一个新的Object 添加到起始Array,那将如何完成?我见过SuccCons 的示例,例如,后继构造函数,但它们只是创建一个递归的嵌套对象,例如

val four = Succ (Succ (Succ (Succ Zero)))

...但这没有帮助...

【问题讨论】:

    标签: list sml abstract-data-type


    【解决方案1】:

    感谢 molbdnilo 帮助创建“JSON 的缺点”功能。附上解决方案的尾递归版本:

    fun make_silly_json i =
        let fun aux(i, acc) =
            if i = 0
            then acc
            else let val json_val = Object[("n", Num(int_to_real(i))),("b", True)]
                     fun json_con (obj, (Array os)) =
                        Array(obj::os)
                      | json_con (_,_) = (Array [])
                 in
                    aux(i-1, json_con(json_val, acc))
                 end
        in aux(i, Array[])
        end
    

    【讨论】:

      【解决方案2】:

      在 molbdnilo 的帮助下,我克服了如何创建Array 列表的思维障碍。由于Array也是一个构造函数,也就是像函数一样,我们可以在这个构造函数调用里面做一些事情,也就是我们可以在Array构造函数里面做一个普通的list consinside

      fun json_cons (ob, (Array os)) = Array (ob::os)
        | json_cons (_,_) = (Array [])
      

      测试

      - json_cons (Object[("a", Num (1.0)),("b", True)], Array[])
      val it = Array [Object [(#,#),(#,#)]] : json
      

      这是另一个直接构造的例子

      - Array (Object [("a", Num 1.0)] :: ([Object [("a", Num 2.0)]]))
      val it = Array [Object [(#,#)],Object [(#,#)]] : json
      

      对于习惯于 1::[2] 的人来说,这很奇怪,尤其是 ([Object[...]]) 作为 cdr 部分。所以这里是代码

      fun make_silly_json (i) =
          case i of
              0 => Array [Object []]
            | x => json_cons (Object [("n", Num (Real.fromInt (x))),("b", True)], make_silly_json (x-1))
      

      测试

      make_silly_json 3
          val it = Array [Object [(#,#),(#,#)],Object [(#,#),(#,#)],Object [(#,#),(#,#)],Object []] : json
      

      ...类型...

      【讨论】:

        【解决方案3】:

        Array [...] 不是json list,而是json,而:: 不能将两个jsons 合并到一个列表中。

        您需要在Array“内部”的列表中加入:

        Array (Object [("a", Num 1.0)] :: ([Object [("a", Num 2.0)]]))
        

        您可能想要添加一个“JSON 的缺点”功能;像

        fun json_cons o (Array os) = Array (o :: os)
          | json_cons _ _ = ... handle structural error ...
        

        您也可以发明自己的二元中缀运算符,但这对于此分配可能有点高级。

        【讨论】:

        • 谢谢,这让我又开始了。然而,([Object [("a", Num 2.0)]])json list 就像 [2]'a list 的事实看起来很奇怪,我会经历很多“猜测-测试”循环。
        • [2]int list,而不是'a list(您不能创建'a list,因为它们不存在); 2 是一个int,在它周围添加[] 会形成一个int list。如果表达式e 的类型为json,则[e] 的类型为json list
        • 很好,但是为什么[Object [("a", Num 2.0)]] 周围的括号必须用于列表consing?如果[2] 是一个int list,为什么不只是[Object [("a", Num 2.0)]] 一个json list 准备好consing?相反,我需要([Object [("a", Num 2.0)]]) 来做consing。
        • 好吧,你把我弄到了……括号实际上是不必要的,因为:: 的优先级很低。为了清楚起见,我把它们放在那里,但Array (Object [("a", Num 1.0)] :: [Object [("a", Num 2.0)]]) 也可以。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-11-24
        • 2017-02-19
        • 2019-11-28
        • 1970-01-01
        • 1970-01-01
        • 2013-11-17
        • 1970-01-01
        相关资源
        最近更新 更多