【问题标题】:Writing several unit definitions?写几个单元定义?
【发布时间】:2021-03-18 14:39:09
【问题描述】:

我见过许多 OCaml 程序,它们的所有功能都在顶部,然后是单元定义,例如:

let rec factorial num =
  if num = 0 then 1
  else num * factorial (num-1)

let () =
  let num2 = read_int () in
    print_int (factorial num2)

这是为什么?它的作用类似于主要功能吗?如果是这样,您应该不能使用其中的几个,对吗? 例如,处理多个输入的最佳方法是什么?写几个单元定义?

【问题讨论】:

    标签: io ocaml main


    【解决方案1】:

    是的,模块顶层的单元表达式就像模块的主函数一样。即,它在程序启动时执行。

    在任何可以有一个单位表达式的地方,您都可以有多个单位表达式。 ; 运算符专门用于此类情况:

    let () =
        Printf.printf "hello\n";
        Printf.printf "world\n"
    

    作为旁注,我经常在我的主模块中编写一个主函数:

    let main () =
        (* main calculation of program *)
    
    let () = main ()
    

    这可能是我多年来编写 C 代码的遗留问题。

    我在其他人的代码中也看到了这一点(可能我们很多人曾经写过 C 代码)。

    【讨论】:

    • 它使程序的入口点对读者更清楚,并强制mainunit -> unit
    【解决方案2】:

    我真的很喜欢 Jeffrey 的回答,但如果您想了解更多详细信息以及了解let () = foo 的含义,这里是一些课外阅读。

    抽象地说,OCaml 程序的操作可以定义为一种机器,它可以简化表达式,直到它们变得不可约。一个不可约的表达式被称为一个。例如,5 + 3 减少到 8 并且没有其他方法可以减少 8 所以 8 是一个值。一个更复杂的值示例是(fun x -> x + 1)。一个更复杂的表达示例是

    (fun x -> x + 1) 5
    

    简化为6

    语言的整个语义被定义为一组这样的归约规则。 OCaml 中的程序是表单定义的有序列表,

    let <pattern> = <expression>
    

    因此,当 OCaml 程序被评估(执行)时,它会减少每个定义的部分并将其分配给左侧的模式,例如,

    let 5 = 2 + 3
    

    是 OCaml 中的有效定义。它将2 + 3 表达式简化为5,然后尝试将结果值与左侧匹配。如果匹配,则评估下一个定义,依此类推。如果不是,则程序终止。

    这里的5 是一个非常简单的值,它只与5 匹配,一般来说,您的值会更复杂。但是,有一个比5 更原始的值。这是一个unit 类型的值,它只有一个居民,表示为()。这也是减少带有副作用的口语表达的价值。由于在 OCaml 中每个表达式都必须归约为一个值,因此我们需要一个不代表任何值的值,即单位。例如,print_endline "foo" 减少为 (),其副作用是将字符串 foo 发送到标准输出。

    因此,当我们写

    let foo () = print_endline "foo"
    let () = foo ()
    

    我们评估(减少)函数foo,直到它达到() 值,这表明我们完全减少了foo ()

    我们也可以使用通配符匹配器并写

    let _ = foo ()
    

    或将结果绑定到变量,例如,

    let bar = foo ()
    

    但是在表达式的左侧使用() 被认为是一种很好的样式,该表达式的计算结果为(),以表明右侧不会产生任何有趣的值。它还可以防止常见错误,例如,

    let () = foo
    

    会产生一个错误,指出unit -&gt; unit 不能与unit 匹配,甚至提供提示:Did you forget to provide ()' 作为参数?`

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-21
      • 1970-01-01
      • 1970-01-01
      • 2021-11-15
      • 2015-01-19
      • 1970-01-01
      • 1970-01-01
      • 2019-07-21
      相关资源
      最近更新 更多