Ocaml中的括号
我正在Ocaml顶级中评估一段非常简单的代码:Ocaml中的括号,ocaml,Ocaml,我正在Ocaml顶级中评估一段非常简单的代码: let p5 () = print_int 5;; p5 ();; print_string "*************************";; let p4 = print_int 4;; p4;; 它返回: val p5 : unit -> unit = <fun> # 5- : unit = () # *************************- : unit = () # 4val p4
let p5 () = print_int 5;;
p5 ();;
print_string "*************************";;
let p4 = print_int 4;;
p4;;
它返回:
val p5 : unit -> unit = <fun>
# 5- : unit = ()
# *************************- : unit = ()
# 4val p4 : unit = ()
# - : unit = ()
val p5:unit->unit=
#5-:单位=()
#*********************-:单位=()
#4val p4:单位=()
#-:单位=()
我的问题是
let p5()=print_int 5;中,()
是什么意思代码>
#5-:unit=()
中-
和()
是什么意思p4
是一种功能吗#4val p4:unit=()
的开头有4
()
来隐藏副作用,有人能给我举个例子吗()
是单位类型值。单位类型是只有一个值的类型。这通常用于生成要么不返回任何有意义的函数,要么不获取任何有意义的函数。请记住,在OCaml中,所有函数都必须返回一些内容并接受一些参数,因此使用单元类型来绕过此限制。在C、C++或java中,类似于5
由print_int
功能打印,而不是由顶层打印。顶层只返回-:unit=()
,而不返回5
。toplevel告诉您它没有创建任何新的绑定-
,最后返回的值是单元类型的,并且具有值()
4
由print\u int
功能打印。此时,toplevel告诉您,它创建了一个新的绑定p4
,该变量携带的值类型为unit
,存储的值为()
()
不用于隐藏副作用。它通常用于创建具有副作用的函数,因此不需要接受任何类型的参数LiKao已经解释了所有的关键点,但我认为如果你一次只输入一行定义,这会显示哪些响应来自哪些输入,可能更有意义。此人输入的行以
#
开头
这有点令人困惑。5
由函数p5
编写。其余部分是来自OCaml顶层的响应。这意味着表达式的结果是类型unit
,并且具有值()
。有道理,print\u int
是int->unit
类型
# print_string "*************************";;
*************************- : unit = ()
# p4;;
- : unit = ()
这里也有类似的困惑。星号*
由print\u string
写入。其余部分显示结果,其类型同样为unit
,值为()
这里也一样。4
由print\u int
编写。其余部分显示顶层定义了一个名为p4
的符号,其类型为unit
,其值为()
。同样,这是有意义的,因为print\u int
返回unit
类型,并且()
是该类型的唯一值。从p4
的类型可以看出它不是一个函数。函数的类型中有一个箭头(->
)p4
只是unit
类型的值
# print_string "*************************";;
*************************- : unit = ()
# p4;;
- : unit = ()
在这里,您向顶层询问
p4
的类型和值,它(再次)告诉您p4
属于unit
类型,并且具有()
值。最后一个问题是如何使用()
来“隐藏副作用”。您可能指的是函数的延迟求值。以下是一个例子:
let p x = print_string "abc";;
let q = print_string "abc";;
p
和q
之间有着至关重要的区别。区别在于p
是'a->unit
类型的函数,q
是unit
类型的值。定义p
时,不会打印任何内容。仅当您将函数p
应用于参数时,即当您计算p1
或p“blah”
或任何值时,才会打印字符串“abc”。(函数p
接受任何类型的参数并忽略它们。)因此在p
的情况下,您在函数内部“隐藏了一个副作用”
在“px”的定义中,有一个参数“x”是没有意义的,因为“x”根本不用。为了简单起见,使用了类型“unit”,因此“p”的定义看起来像“let p()=…”。这和
let p = fun () -> print_string "abc";;
然后将函数“p”用作“p()”。如果您首先学习了C、Java等编程语言,其中()用于所有函数的参数,那么这可能会令人困惑。但在OCAML中,()
是一个表示“空值”的特殊符号,该值有一个称为“单位”的特殊类型
定义
q
时会发生完全不同的事情:字符串“abc”立即打印,因为这是计算“print\u string”的副作用,q
等于()
,因为()
是通过计算“print\u string”得到的结果值。我迟到了,但我想指出的是,在
let p5 () = print_int 5
在参数p5
中具有模式匹配。这相当于:
let p5 x = match x with () -> print_int 5
或者这个:
let p5 = function () -> print_int 5
甚至这个:
let p5 = fun x -> match x with () -> print_int 5
这种区别在以下代码中很重要:
let f (x, y) = print_int (x + y)
let g x y = print_int (x + y)
f
只接收一个参数(该对(x,y)
),而g
接收两个参数f
因此具有类型(int*int)->unit
,g
具有类型int->int->unit
。所以f
可以这样写:
let f pair = match pair with (x, y) -> print_int (x + y)
您可能希望习惯使用
print\u endline
而不是print\u string
,因为它可以自动
let f pair = match pair with (x, y) -> print_int (x + y)