【问题标题】:convert int to natural number in ocaml在ocaml中将int转换为自然数
【发布时间】:2019-09-28 17:24:49
【问题描述】:

我正在尝试在 OCaml 中编写一个将整数转换为自然数的函数。这是我的代码

type nat = Zero | Succ of nat 
let rec int_to_nat (x:int):nat option=
    if x<0 then
        None
    else if x=0 then
        Some Zero
    else
        Succ(int_to_nat (x-1));;

编译器提示“This variant expression is expected to have type nat option.The constructor Succ does not contain type option”错误。我不明白这是什么意思。

【问题讨论】:

  • 这就是它所说的意思。 Succ(...) 具有 nat 类型,但 ti 期望 nat option,如 Some (Succ ...),因为这是 if 表达式的其他两个分支返回的内容。它们都需要返回相同的类型,否则整个if 表达式的类型会是什么?

标签: compiler-errors ocaml


【解决方案1】:

您不应该将类型更改为“Succ of nat option”,因为生成的类型没有意义。相反,您可以在函数中返回具有适当类型的值:

type nat = Zero | Succ of nat

let rec int_to_nat (x:int) : (nat option) =
  if x < 0 then None else
  match x with
  | 0 -> None
  | _ -> let y = int_to_nat (x-1) in
    match y with
    | None -> None
    | Some z -> Some (Succ z);;

但是,这将导致大 x 的堆栈溢出。您可以通过使其尾递归来解决此问题:

type nat = Zero | Succ of nat

let int_to_nat (x:int) : (nat option) =
  if x < 0 then None else
  let rec int_to_nat' (x:int) (accum:nat) : (nat option) =
    match x with
    | 0 -> Some accum
    | _ -> int_to_nat' (x-1) (Succ accum)
  in int_to_nat' x Zero;;

关于尾递归,您可能会发现 blog post 中的可视化很有用。

【讨论】:

    【解决方案2】:

    它需要一个 nat 选项。这是我改变的地方

    type nat = Zero | Succ of nat option
    let rec int_to_nat (x:int):nat option=
        if x<0 then
            None
        else if x=0 then
            Some Zero
        else
            Some Succ(int_to_nat (x-1));;
    

    【讨论】:

      猜你喜欢
      • 2017-03-26
      • 2015-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多