我在OCaml中做出差异化功能,但我遇到了一些问题

时间:2016-11-03 08:38:39

标签: list ocaml differential-equations

首先,这是我的代码:

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列表。 无法找到问题所在。

3 个答案:

答案 0 :(得分:2)

对我来说,这部分看起来是:Times[diff (h, var);t]。由于taexp 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,因为它们可以告诉正确的程序结构。手压痕经常会让你眼前一亮。