我在 OCaml 中做微分函数,我遇到了一些问题
I'm making differentiating function in OCaml and I have some problems
首先,这是我的代码:
module Problem1 = struct
type aexp =
| Const of int
| Var of string
| Power of string * int
| Times of aexp list
| Sum of aexp list
let diff : aexp * string -> aexp
= fun (exp, var) ->
match exp with
|Const a -> Const 0
|Var x -> if x = var then Const 1 else Var x
|Power (s, i) ->
if s = var then Times[Const i;Power (s, i - 1)] else Power (s, i)
|Times l ->
match l with
|h::t -> Sum[Times[diff (h, var);t];diff (t, var)]
|Sum m ->
match m with
|h::t -> Sum[diff(h, var); diff(t, var)];;
end
口译员说,
Error: This variant pattern is expected to have type aexp list
The constructor Sum does not belong to type list
但我希望符号 m 是一个 aexp 列表。
找不到问题所在。
对我来说,这部分看起来不对:Times[diff (h, var);t]
。由于 t
是一个 aexp list
,您应该使用另一个列表构造函数 ::,使其成为 `Times (diff (h, var) :: t).
如果你把 match .. with ..
放在另一个 match .. with
的盒子里,你需要用 begin
包裹里面的盒子 .. end
:
(* I do not check the code is correct *)
let diff : aexp * string -> aexp
= fun (exp, var) ->
match exp with
|Const a -> Const 0
|Var x -> if x = var then Const 1 else Var x
|Power (s, i) ->
if s = var then Times[Const i;Power (s, i - 1)] else Power (s, i)
|Times l ->
begin match l with
|h::t -> Sum[Times[diff (h, var);t];diff (t, var)]
end
|Sum m ->
match m with
|h::t -> Sum[diff(h, var); diff(t, var)]
请安装合适的自动缩进工具,例如 tuareg 或 ocp-indent,因为它们可以告诉您正确的程序结构。手印往往会骗过你的眼睛。
实际上你的问题很简单,你会通过使用知道如何缩进 OCaml 代码的工具看到它;-)
看看你的最后几行是如何用 OCaml 压头缩进的:
|Times l ->
match l with
|h::t -> Sum[Times[diff (h, var);t];diff (t, var)]
|Sum m ->
match m with
|h::t -> Sum[diff(h, var); diff(t, var)];;
是的,没错,因为你在Times l
中创建了一个新的模式匹配,Sum m
被包含在其中。你应该写
|Times l -> begin
match l with
|h::t -> Sum[Times[diff (h, var);t];diff (t, var)]
end
|Sum m ->
match m with
|h::t -> Sum[diff(h, var); diff(t, var)];;
它会工作得很好。
顺便说一句,你会遇到另一个问题,因为你没有写 let rec diff ...
而是 let diff
并且你正在递归调用 diff
。
首先,这是我的代码:
module Problem1 = struct
type aexp =
| Const of int
| Var of string
| Power of string * int
| Times of aexp list
| Sum of aexp list
let diff : aexp * string -> aexp
= fun (exp, var) ->
match exp with
|Const a -> Const 0
|Var x -> if x = var then Const 1 else Var x
|Power (s, i) ->
if s = var then Times[Const i;Power (s, i - 1)] else Power (s, i)
|Times l ->
match l with
|h::t -> Sum[Times[diff (h, var);t];diff (t, var)]
|Sum m ->
match m with
|h::t -> Sum[diff(h, var); diff(t, var)];;
end
口译员说,
Error: This variant pattern is expected to have type aexp list
The constructor Sum does not belong to type list
但我希望符号 m 是一个 aexp 列表。 找不到问题所在。
对我来说,这部分看起来不对:Times[diff (h, var);t]
。由于 t
是一个 aexp list
,您应该使用另一个列表构造函数 ::,使其成为 `Times (diff (h, var) :: t).
如果你把 match .. with ..
放在另一个 match .. with
的盒子里,你需要用 begin
包裹里面的盒子 .. end
:
(* I do not check the code is correct *)
let diff : aexp * string -> aexp
= fun (exp, var) ->
match exp with
|Const a -> Const 0
|Var x -> if x = var then Const 1 else Var x
|Power (s, i) ->
if s = var then Times[Const i;Power (s, i - 1)] else Power (s, i)
|Times l ->
begin match l with
|h::t -> Sum[Times[diff (h, var);t];diff (t, var)]
end
|Sum m ->
match m with
|h::t -> Sum[diff(h, var); diff(t, var)]
请安装合适的自动缩进工具,例如 tuareg 或 ocp-indent,因为它们可以告诉您正确的程序结构。手印往往会骗过你的眼睛。
实际上你的问题很简单,你会通过使用知道如何缩进 OCaml 代码的工具看到它;-)
看看你的最后几行是如何用 OCaml 压头缩进的:
|Times l ->
match l with
|h::t -> Sum[Times[diff (h, var);t];diff (t, var)]
|Sum m ->
match m with
|h::t -> Sum[diff(h, var); diff(t, var)];;
是的,没错,因为你在Times l
中创建了一个新的模式匹配,Sum m
被包含在其中。你应该写
|Times l -> begin
match l with
|h::t -> Sum[Times[diff (h, var);t];diff (t, var)]
end
|Sum m ->
match m with
|h::t -> Sum[diff(h, var); diff(t, var)];;
它会工作得很好。
顺便说一句,你会遇到另一个问题,因为你没有写 let rec diff ...
而是 let diff
并且你正在递归调用 diff
。