首先,这是我的代码:
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列表。 无法找到问题所在。
答案 0 :(得分:2)
对我来说,这部分看起来是:Times[diff (h, var);t]
。由于t
是aexp list
,你应该使用另一个列表构造函数::,使它成为`Times(diff(h,var):: t)。
答案 1 :(得分:2)
实际上你的问题很简单,你可以通过使用知道如何缩进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
。
答案 2 :(得分:1)
如果您将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,因为它们可以告诉正确的程序结构。手压痕经常会让你眼前一亮。