咖喱
add::Int->Int->Int
add x y = x+y
未经证实
add1::(Int,Int)->Int
add1 (x,y)=x+y
我有几个问题重新排列 Curried 和 Uncurried 功能,考虑上面的功能,
是(Int,Int)
,那么它是否与元组的输入相等?我们怎么能区分那个?
关于无故障和咖喱功能的优缺点是什么?什么时候和为什么要使用?
答案 0 :(得分:9)
在Uncurried函数输入参数中为(Int,Int),它是否与输入元组相等?我们怎么能区分那个?
它不仅仅是等价的,而且是一个元组。所以add1
是一个函数,它接受一对(2元组)的Ints并返回一个Int。
关于无故障和咖喱功能的利弊是什么? ,以及在哪里使用它们?
根据经验,我会说:如果你没有充分的理由不使用咖喱功能。
他们有一个很好的功能,你可以部分应用它们,例如您可以编写f = add 1
,其中f
现在的类型为f :: Int -> Int
,并且始终为其参数添加1。
这有许多应用程序,并且在Haskell中非常常见,因为它非常方便。例如。向列表中的所有元素添加1的函数只是map (add 1)
。
另外,语法噪音要小得多。
答案 1 :(得分:4)
我喜欢@ bzn的答案,但我想举几个例子说明未使用的功能在哪些方面有用。
有些库大量使用数据元组。一个例子是Gtk2hs,它使用元组(Int, Int)
来表示窗口大小和某些坐标。因此,当我使用gtk2hs时,我会经常以未经处理的形式编写函数,因此我不必手动解包元组。
还记得一个函数只能返回一个结果。要返回多个值,需要将所有结果打包到元组中。然后uncurry
可用于从这些函数中创建组合。这是我正在研究的项目的简化示例:
addIndex :: MyData -> (Int, MyData)
normalize' :: Int -> MyData -> [(Int, MyData)]
normalize :: [MyData] -> [(Int, MyData)]
normalize = concatMap (uncurry normalize' . addIndex)
我通常更喜欢以咖喱形式编写函数,但在这里我需要normalize'
的未经验证的版本与addIndex
一起构成。
在这两种情况下,我发现一个非常有用的功能。幸运的是,在两种形式之间进行转换很容易。