У меня есть этот тип данных
datatype json =
Num of real
| String of string
| False
| True
| Null
| Array of json list
| Object of (string * json) list
и этот код
fun mymatch (jobj,str) =
case jobj of
Array [] => NONE
| Array(Object oh::[]) => mymatch (Object oh, str)
| Array (Object oh::ot) =>
if isSome (assoc(str, oh)) then assoc(str, oh) else mymatch (Array ot, str)
| Object xs => assoc (str, xs)
| _ => NONE
с этой вспомогательной функцией
fun assoc (k, ls) =
case ls of
[] => NONE
| (a,b)::[] => if k = a then SOME b else NONE
| (a,b)::xs => if k = a then SOME b else assoc (k,xs)
, которая должна принимать что-то вроде этого
mymatch (Array [Object [("n", Num (4.0)),("b", True)],Object [("last", Num (4.0)),("foo", True)]],"foo")
и верните совпадение в string
«foo», ища каждый Object
в Array
. Как вы можете видеть в коде, я на самом деле обрабатываю только две вещи в json
, которые соответствуют критериям, то есть Array
, который содержит Objects
с, затем отправка Object
s для проверки , Этот код работает, но он наверняка из бруталистической школы программирования, т. Е. Он выглядит как клудж. Почему? Из-за случая в mymatch
, когда мне нужно пройти через Array
...
| Array (Object oh::ot) =>
if isSome (assoc(str, oh)) then assoc(str, oh) else mymatch (Array ot, str)
...
До сих пор я имел дело только с рекурсией в списках, где вы проверяете автомобиль, а затем выполняете рекурсию на корд. Опять же, этот код работает, но я чувствую, что что-то упустил. Мне нужно проверить голову Object
из Array
и завершить, если она совпадает; в противном случае продолжайте повторять - все в мире возвращения option
. Есть ли более элегантный способ сделать это?