柯里化函数类型中括号的区别

问题描述 投票:0回答:3

这些返回类型有什么不同?

val fn1 : int −> (int −> (int −> int))
val fn2: (int −> int) −> (int −> int)

这创建了一个类型为

的函数
int -> int -> int    meaning    int -> (int -> int)

是吗?不带括号它们的意思是一样的!

sml smlnj ml
3个回答
3
投票

正如你所说,

fn1
的函数类型相当于
int -> int -> int -> int

当您有多个像 fn1 a b c 这样的

curried
参数时,那么
fn1 a
int -> int -> int
类型的函数,而
fn1 a b
int -> int
类型的函数。因此
fn1
也可以被视为一个返回函数的函数,该函数返回一个返回
int
的函数。添加像
int -> (int -> (int -> int))
这样的括号会突出显示该解释。

函数

fn2
有所不同:它采用
int -> int
类型的函数作为参数,并返回另一个
int -> int
类型的函数。


0
投票

SML 中的函数采用一个参数并返回一个值。 故事结束。

嗯,不完全是。

当我们需要向函数传递多个参数时,有两种方法可以做到这一点。您可以将元组或记录或其他聚合数据结构传递给函数。这是一个单一的值,但却是由多条数据组成的。

fun f (x, y) = x * 3 + y

柯里化的来源是函数也是值,并且函数返回单个值。该值可以是一个函数。所以我们可以写:

val f = fn x => fun y => x * 3 + y

这很乏味,所以我们可以写成:

fun f x y = x * 3 + y

这非常适合部分应用:将通过将一个参数应用于

f
返回的函数绑定到一个新名称,然后在其余参数上调用它。

val g = f 3;
val h = g 1; (* 10 *)

f
这样的函数可以被赋予类型
int -> (int -> int)
,因为它描述了它的作用:给定
int
值,返回一个接受
int
并返回
int
的函数。但是
int -> int -> int
等效地描述了这一点。

现在,如果您看到

(int -> int) -> int
,则描述的是不同的东西。这意味着该函数接受一个函数作为参数并返回一个
int

执行此操作的函数示例:

fun g f = 1 + f 5

由于

int -> int
函数表示作为参数传入的一个值,因此无法从类型签名
(int -> int) -> int
中删除括号。


0
投票

让我们分解一下

fn1
fn2
的返回类型来了解它们的区别:

1.

fn1: int -> (int -> (int -> int))

  • 该函数接受一个整数作为输入并返回一个函数。返回的函数接受一个整数作为输入并返回另一个函数。最后,最里面的函数接受一个整数作为输入并返回一个整数。
  1. fn2: (int -> int) -> (int -> int)
    • 该函数接受一个函数作为输入,该函数本身接受一个整数作为输入并返回一个整数。然后,外部函数返回另一个函数,该函数也接受一个整数作为输入并返回一个整数。

现在,让我们看看这些类型在应用时如何发挥作用:

  • 对于
    fn1
    ,你可以这样称呼它:
    val result = fn1(5)(10)(15)
    

这意味着

fn1
被赋予
5
作为其初始参数,从而导致另一个函数的返回。随后,该函数被赋予
10
作为参数,并返回一个不同的函数。最后,最里面的函数接收
15
并返回结果。

  • 对于
    fn2
    ,你可以这样称呼它:
    val result = fn2(x => x * 2)(10)
    
    这里,
    fn2
    采用函数
    x => x * 2
    作为其第一个参数,该函数本身就是一个将其输入加倍的函数。然后,外部函数返回一个新函数,该函数将
    10
    作为输入,从而得到
    20

所以,总结一下:

  • fn1
    返回一个嵌套函数,该函数依次接受多个参数。

  • fn2
    生成一个函数,该函数接收另一个函数作为其输入,后跟其自身的参数。

当您最初查看它们时,它们可能看起来很相似,但区别在于它们的返回类型的结构和实现方式。返回类型中的括号对于理解函数的行为和应用至关重要。

© www.soinside.com 2019 - 2024. All rights reserved.