我正在学习Jason Hickey's Introduction to Objective Caml。只是对嵌套函数(currying)提出疑问。
现有问题How to understand the "Currying" in Haskell?,但我想我正在寻找稍微不同的问题的答案。
它表示我们可以将let sum = fun i j -> i + j;;
写为let sum = fun i -> fun j -> i + j;;
我的问题很简单:
我能否以这种方式理解上述定义:let sum = fun i -> i + fun j -> j;;
?
我知道它不会通过编译器,但我只是尝试将这种OCaml function definition
映射到mathematics functions
。
在我的想象中,我们可以在数学中轻松地编写函数f(i) = i + g(j); and g(j) = j
。
我是否应该总是进行这种逻辑映射以便于理解?
答案 0 :(得分:3)
你的想象力并不正确:f(i) = i + g(j)
并不意味着j
在这里未定义。
理解fun i j -> foo
的正确方法是将其视为更明确的符号fun i -> fun j -> foo
的一些方便的语法糖。
以下所有定义完全相同:
let sum i j = i + j
let sum i = fun j -> i + j
let sum = fun i -> (fun j -> i + j)
let sum = fun i -> fun j -> i + j
let sum = fun i j -> i + j
let sum i =
let add_i = fun j -> i + j in
add_i
在数学上这可以写成(i↦(j↦i + j)),作为...的元素 功能空间(ℕ→(ℕ→ℕ))。
答案 1 :(得分:1)
OCaml函数可以直接映射到数学符号和从数学符号映射。但是,您需要意识到数学符号是模糊的。函数值f(i)
与特定值i
和函数f
本身之间没有明确的区别。当一个人意味着函数f(i)
本身时,通常会写f
。 (“让我们考虑函数f(i)= i + 1 ...此函数是......”)要在OCaml中编写正确的代码,您必须清楚地看到您是使用函数本身还是使用值功能。
当您用数学符号说“考虑函数f(i,j)=i+g(j) where g(j)=j
时,您正在编写函数的值。在OCaml中,这被转换为
let f i j =
let g j = j in
i + g j;;
或
let f =
let g = fun j -> j
in
fun i j -> i + g j;;
如果您正在尝试编写let sum = fun i -> i + fun j -> j;;
,那么在数学符号中您会说“考虑函数sum
,使sum(i) = i + g
,其中g是由{{1}定义的函数}“。这在数学上是不正确的:您无法添加整数值 g(j)=j
和函数 i
。您只能在某个其他整数g
上添加函数i
的整数g
和值。严格来说,表达“j
”是不确定的。您要么写i+g
,要么i + g(i)
,而不是i+g(j)
。这在数学中是如此,在OCaml中也是如此。