所以我已经定义了我自己的类型:
type test = Empty
| Int of int
| Str of string
| List of test list;;
我正在尝试遍历列表并评估每个头但我似乎无法使其工作。
type evalRes = Next /* | other matches just ignore this. It's needed for something else */;;
let rec eval (test:test) : (evalRes) = match test with
| Int i -> /* do int stuff */; Next
| Str s -> /* string stuff */; Next
| List(stmt1::tail) -> eval stmt1;;
我知道只评估第一个。我怎样才能评估列表的其余部分?我的类型测试将有更多的案例要匹配,这只是一个基本的测试。
答案 0 :(得分:0)
tail
的类型为test list
,这意味着您需要一些可以接受test list
的功能。一个好的开始是看List.map
和List.fold
。当然,在这种情况下,你甚至不需要解构列表。困难的部分是决定如何合并每个陈述的结果。
答案 1 :(得分:0)
如果您确实要在eval
上递归应用tail
,则需要将其重新设置为test
。这可以通过以下方式实现:
let rec eval (test:test) : evalRes = match test with
| Int i -> /* do int stuff */; Next
| Str s -> /* string stuff */; Next
| List(stmt1::tail) -> (eval stmt1) ++ (eval (List tail))
显然,正如ivg所建议的,在这种情况下使用List.fold
似乎更合适:
let rec eval (test:test) : evalRes = match test with
| Int i -> /* do int stuff */; Next
| Str s -> /* string stuff */; Next
| List l -> List.fold_left (fun res test -> res ++ (eval test)) Next l
(++)
是处理evalRes
序列的方式。
let (++) a b = b
(可能比这更有趣)。