如何解决如何在 OCaml 上使用 fold 编写 contains_var 函数?
我有以下 fold_expr
函数,它递归地折叠任何任意表达式,包括浮点数、变量、二元运算符和否定。
let rec fold_expr (e : expression) (f: float -> 'a) (v: 'a) (b: binop -> 'a -> 'a -> 'a) (n: 'a -> 'a)
现在我正在尝试实现一个名为 contains_var
的函数,如果表达式有变量,则返回 true,否则返回 false。我知道 contains_var
可以这样递归实现:
let rec contains_var (e:expression) : bool =
match e with
| Num _ -> false
| Var -> true
| Neg _ -> false
| Binop (_,e1,e2) -> contains_var e1 || contains_var e2
;;
我尝试如下实现它:
let contains_var (e:expression) : bool =
let Num _ = false in
let Var = true in
let Binop bin,l,r = l || r in
let Neg _ = false
fold_expr e _ Var bin _
显然我在编译时遇到了麻烦,而且我确定我遗漏了一些东西。任何帮助表示赞赏! :)
解决方法
从 fold_expr
的角度来看,这个函数似乎做了以下事情:
val fold_expr (e : expression) (f: float -> 'a) (v: 'a) (b: binop -> 'a -> 'a -> 'a) (n: 'a -> 'a)
fold_expr e f v b n
:
- 如果
f
为n
,则将e
应用于Num n
, - 如果
v
为e
,则返回Var
, - 如果
b
为bop
,则将fold_epxr e1
应用于fold_expr e2
、e
和Binop (bop,e1,e2)
- 并将
n
应用到e1
,如果e
是Neg e1
您需要做的是将与您的问题对应的值提供给 fold_expr。在这种情况下,除了 false
和 Var
Binop
的函数
解决方案可能如下所示:
let contains_var e = fold_expr e (fun _ -> false) true what_is_b (fun _ -> false)
我可以给你what_is_b
,但我认为这是你需要自己找到的主要问题,所以我会把它留给你。
折叠可以看作是重新解释构造函数的一种方式。 对于定义为
的列表type 'a l =
| Nil
| Cons of 'a * 'a l
fold(right) 函数可以写成
let rec fold ~nil ~cons = function
| Nil -> nil
| Cons (x,l) -> cons x (fold ~cons ~nil l)
从这一点来说,写一个深恒等函数可以通过将构造函数重写为函数来完成:
let deep_identity l = fold ~nil:Nil ~cons:(fun x l -> Cons (x,l))
类似地,一个(重言式)函数contains_nil
可以写成
let contains_nil = fold ~nil:true ~cons:(fun _ contains_nil -> contains_nil)
fold_expr
函数只是一个稍微复杂一点的版本,它将 Var
、Num
、Binop
和 Neg
的函数版本作为参数.
因此,要编写 contains_var 函数,您需要:
- 定义正确的
var
、num
、binop
和neg
函数 - 使用上面定义的函数调用
fold_expr
。
注意函数名和变量名不能以大写字母开头;并且您不能使用 _
作为函数应用程序的参数。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。