我通过阅读"为了Goog而学习你的Haskell"来学习Haskell!书.我想确定我正确地理解这是"讨好".
我理解一个函数不能得到一个以上的参数.当一个函数有一个以上的参数时,它实际上是一个带有一个参数的函数.即:
func :: Int -> Int -> Int -> Int
Run Code Online (Sandbox Code Playgroud)
像这样工作(并且是相同的):
func :: Int -> (Int -> (Int -> Int))
Run Code Online (Sandbox Code Playgroud)
即一个函数返回一个函数,它也返回一个函数,等等.这个"嵌套娃娃"行为被称为"currying"(curried函数).代码的第一个变体就像是"语法糖".
可以部分应用具有多于零参数的任何函数.也就是说,可以说"currying"是"部分应用"的反向动作.我对吗?
与咖喱相反的是反复的.
f :: a -> b -> c
f' :: (a, b) -> c
f' = -- uncurried f
f'' :: a -> b -> c
f'' = -- curried f' = f
Run Code Online (Sandbox Code Playgroud)
一个curried函数,尽管它的"语言"arity减少到1,保持"语义"arity不变(因为你仍然必须为元组提供每个值).比较中唯一改变的是传递参数的方式.
部分应用程序是将函数的arity减少到大于0的数字的应用程序.这是一个不可逆转的操作; 你无法不应用参数.
-- 1 2
f :: a -> b -> c
-- 1
f' :: b -> c
f' = f c -- partially applied f
-- 0 arguments
f'' :: c
f'' = f c1 c2 -- fully applied f
Run Code Online (Sandbox Code Playgroud)
也就是说,可以说"currying"是"部分应用"的反向动作.
差不多但反过来说:"Currying"可以看作与"部分应用" 相同的东西.
让我在ghci会议的帮助下解释一下.我们首先为不同类型的函数定义一些类型的同义词.
Prelude> type Binary a b c = (a, b) -> c
Prelude> type Curried a b c = a -> (b -> c)
Prelude> type Unary a b = a -> b
Run Code Online (Sandbox Code Playgroud)
在这里,我们有两种表示二元函数的方法:我们有Binary像数学一样的函数,即接受元组的函数.然后我们Curried通常在Haskell中使用函数,即返回函数的函数.为了完整起见,我们还有一个特殊的Unary功能名称.
现在我们可以使用标准curry和uncurry函数在二元函数的两个表示之间进行转换.在ghci中,我们可以检查如下:
Prelude> :t curry :: Binary a b c -> Curried a b c
curry :: Binary a b c -> Curried a b c
:: Binary a b c -> Curried a b c
Prelude> :t uncurry :: Curried a b c -> Binary a b c
uncurry :: Curried a b c -> Binary a b c
:: Curried a b c -> Binary a b c
Run Code Online (Sandbox Code Playgroud)
(注意,当你输入时:t foo :: SomeType,ghci会检查是否foo有类型SomeType.如果是,ghci将再次打印.如果没有,ghci会抱怨).
因此,作为鲍尔泰克正确他的回答指出,逆curry是uncurry.但我们也可以理解curry如下类型:
Prelude> :t curry :: Binary a b c -> a -> Unary b c
curry :: Binary a b c -> a -> Unary b c
:: Binary a b c -> a -> Unary b c
Run Code Online (Sandbox Code Playgroud)
如果我们写这样的类型,我们看到我们可以curry用来部分应用一个Binary函数:给定一个f :: Binary a b c和第一个参数,x :: a我们可以curry f x用来产生一个Unary b c仍然在等待类型的第二个参数b.
| 归档时间: |
|
| 查看次数: |
158 次 |
| 最近记录: |