Arrows 是函数的真正概括吗?
Are Arrows a true generalization of functions?
箭头通常被描述为函数的泛化(仅静态生成的函数,即不支持部分应用程序/闭包)。但是,至少看一下在 Haskell 中建模的 Arrows,我看不出它们如何概括多个参数的函数 return 一个结果(通常可能不是一个结果元组)。我试图设想如何仅使用箭头界面就可以得到箭头的组合,从而产生一个通常可能不是元组的结果。有没有办法做到这一点,或者这是对 Arrow 类型功能的故意限制?
据我所知,箭头提供了组合静态(可能是并行的)管道的能力,但它们不能 'fold' 将输出的元组组合成单个最终结果。是我错了还是我遗漏了什么?
你可以想到type
的函数
f :: a -> b -> c
作为一个接受类型 a
的值并生成另一个类型 b -> c
的函数的函数。也就是说,
f :: a -> (b -> c)
箭头的概括非常简单:
f :: Arrow a (Arrow b c)
为了使用多个变量进行函数组合,您必须使用 (.)
运算符或 (<<<)
进行一些疯狂的语义操作。与 makes functions with multiple arguments pointfree cumbersome 阻碍语法以这种方式表示箭头的原因相同,这就是为什么有这么多组合器使用元组的原因。此外,没有什么能阻止您定义将元组映射到值的箭头。 arr
函数把任意函数变成箭头!
f :: (a, b) -> c
af :: Arrow (a, b) c
af = arr f
I can't see how they can generalize functions of multiple arguments that return a single result
让输入类型为元组,输出为普通值。比如拿箭头
plus :: a (num, num) num
let plus = arr (\(a, b) -> a + b) -- arr (uncurry (+))
或者,您可以采用 "nested arrows" - 具有多个参数的柯里化函数不过是 returns 一个函数的函数。所以我们有一个箭头,其结果是另一个箭头:
plus :: a num (a num num)
let plus = arr (arr . (+))
要使用它,我们需要一个 ArrowApply
实例。首先,您将箭头与另一个箭头组合,从您的输入
创建第二个参数
plusWithIncrement :: a num (a num num, num)
let plusWithIncrement = plus &&& arr (+1)
然后你可以运行那
plusWithIncrement >>> app :: a num num
(这是一种过于复杂的写法arr (\x -> x + (x+1))
)
箭头通常被描述为函数的泛化(仅静态生成的函数,即不支持部分应用程序/闭包)。但是,至少看一下在 Haskell 中建模的 Arrows,我看不出它们如何概括多个参数的函数 return 一个结果(通常可能不是一个结果元组)。我试图设想如何仅使用箭头界面就可以得到箭头的组合,从而产生一个通常可能不是元组的结果。有没有办法做到这一点,或者这是对 Arrow 类型功能的故意限制?
据我所知,箭头提供了组合静态(可能是并行的)管道的能力,但它们不能 'fold' 将输出的元组组合成单个最终结果。是我错了还是我遗漏了什么?
你可以想到type
的函数f :: a -> b -> c
作为一个接受类型 a
的值并生成另一个类型 b -> c
的函数的函数。也就是说,
f :: a -> (b -> c)
箭头的概括非常简单:
f :: Arrow a (Arrow b c)
为了使用多个变量进行函数组合,您必须使用 (.)
运算符或 (<<<)
进行一些疯狂的语义操作。与 makes functions with multiple arguments pointfree cumbersome 阻碍语法以这种方式表示箭头的原因相同,这就是为什么有这么多组合器使用元组的原因。此外,没有什么能阻止您定义将元组映射到值的箭头。 arr
函数把任意函数变成箭头!
f :: (a, b) -> c
af :: Arrow (a, b) c
af = arr f
I can't see how they can generalize functions of multiple arguments that return a single result
让输入类型为元组,输出为普通值。比如拿箭头
plus :: a (num, num) num
let plus = arr (\(a, b) -> a + b) -- arr (uncurry (+))
或者,您可以采用 "nested arrows" - 具有多个参数的柯里化函数不过是 returns 一个函数的函数。所以我们有一个箭头,其结果是另一个箭头:
plus :: a num (a num num)
let plus = arr (arr . (+))
要使用它,我们需要一个 ArrowApply
实例。首先,您将箭头与另一个箭头组合,从您的输入
plusWithIncrement :: a num (a num num, num)
let plusWithIncrement = plus &&& arr (+1)
然后你可以运行那
plusWithIncrement >>> app :: a num num
(这是一种过于复杂的写法arr (\x -> x + (x+1))
)