SML, составляющий список типов данных - PullRequest
0 голосов
/ 10 апреля 2020

Если у меня есть этот тип данных 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 и работать с ::

Да, это домашнее задание из прошлого семестра Языки программирования в U из Вашингтона, что я делаю самостоятельно. Это является назначением.

Моя основная проблема c в том, что я не знаю, как добавить к Array рекурсивные вызовы. Если мне нужно сгенерировать Array, содержащий Objects и добавить новый Object к этому начальному Array с каждым рекурсивным вызовом, как это будет сделано? Я видел примеры Succ или Cons, например, конструктор-преемник, но они просто создают рекурсивный вложенный объект, такой как

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

... но это бесполезно. ..

Ответы [ 2 ]

1 голос
/ 11 апреля 2020

Array [...] - это не json list, это json, и :: не может вывести два json с в список.

Вам необходимо добавить в список "внутри" Array:

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

Возможно, вы захотите добавить функцию "cons для JSON"; что-то вроде

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

Вы также можете изобрести свой собственный бинарный инфиксный оператор, но это, вероятно, немного сложнее для этого назначения.

0 голосов
/ 12 апреля 2020

С помощью molbdnilo я преодолел умственный блок создания списка Array. Поскольку Array также является конструктором, т. Е. Подобно функции, мы можем делать что-то внутри этого вызова функции конструктора, а именно мы можем сделать обычный список cons внутри конструктора Array

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

... типы ...

...