OCaml-何时使用函子
对于何时在代码中使用或实现函子,我有点困惑。我在下面包含了一些代码,其中有两个函数display_expr和cal_expr,这两个函数的形式相同,但实现方式不同。这是不是一个地方,我会考虑创建一个单一的函子,代表两个函数的核心功能?OCaml-何时使用函子,ocaml,Ocaml,对于何时在代码中使用或实现函子,我有点困惑。我在下面包含了一些代码,其中有两个函数display_expr和cal_expr,这两个函数的形式相同,但实现方式不同。这是不是一个地方,我会考虑创建一个单一的函子,代表两个函数的核心功能? type expr = | Add of expr * expr | Minus of expr * expr | Multi of expr * expr | Divide of expr * expr | Value o
type expr =
| Add of expr * expr
| Minus of expr * expr
| Multi of expr * expr
| Divide of expr * expr
| Value of int;;
let rec display_expr e =
match e with
| Add (a1, a2) -> "(" ^ display_expr a1 ^ " + " ^ display_expr a2 ^ ")"
| Minus (m1, m2) -> "(" ^ display_expr m1 ^ " - " ^ display_expr m2 ^ ")"
| Multi (m1, m2) -> "(" ^ display_expr m1 ^ " * " ^ display_expr m2 ^ ")"
| Divide (d1, d2) -> "(" ^ display_expr d1 ^ " / " ^ display_expr d2 ^ ")"
| Value v -> string_of_int v;;
let rec cal_expr e =
match e with
| Add (a1, a2) -> (cal_expr a1) + (cal_expr a2)
| Minus (m1, m2) -> (cal_expr m1) - (cal_expr m2)
| Multi (m1, m2) -> (cal_expr m1) * (cal_expr m2)
| Divide (d1, d2) -> (cal_expr d1) / (cal_expr d2)
| Value v -> v;;
let equ =
Multi(Value 34,
Add(Value 24,
Divide(Value 24,
Minus(Value 10, Value 7)
)
)
);;
Printf.fprintf stdout "%d = %s\n" (cal_expr equ) (display_expr equ);;
注意:我尝试为上述代码编写了一个函子解决方案,当我发现函子需要一个公共类型或组合类型来表示display_expr和cal_expr返回的值时,我得到了一个解决方案
<>我也是一个极端的新手,所以请在你的回复中考虑。谢谢。由于没有模块,函子在这里并不真正适用,但您可以直接使用高阶函数来攻击它 关键是要注意,每个构造函数需要一个转换,因此需要一个函数参数。此模式在某些方面类似于列表。向右折叠,可以将其视为替换列表构造函数的操作
type expr =
| Add of expr * expr
| Sub of expr * expr
| Mul of expr * expr
| Div of expr * expr
| Int of int
let transform ~add ~sub ~mul ~div ~int expr =
let rec tx = function
| Add (x, y) -> add (tx x) (tx y)
| Sub (x, y) -> sub (tx x) (tx y)
| Mul (x, y) -> mul (tx x) (tx y)
| Div (x, y) -> div (tx x) (tx y)
| Int x -> int x in
tx expr
let binary_op_str sep a b = "(" ^ a ^ sep ^ b ^ ")"
let display_expr = transform
~add:(binary_op_str " + ")
~sub:(binary_op_str " - ")
~mul:(binary_op_str " * ")
~div:(binary_op_str " / ")
~int:string_of_int
let cal_expr = transform
~add:(+)
~sub:(-)
~mul:( * )
~div:(/)
~int:(fun x -> x)
这是否比您的原始代码更可取是一个品味问题。您的functor解决方案是什么样子的?我很难想象它,因为函子本质上是从一个模块到另一个模块的函数,而你给出的代码中没有任何模块。这是为了给我提供这样一个干净的解决方案。我真的很感激。在我看到你做了什么之前,我必须仔细检查你的代码。很好的解决方案。如果参数数量增加,您可以使用包含这些传递函数的实现的函子。或者创建一个包含所有这些函数的记录。但这对于问题的范围是有利的。