Haskell curried和uncurried函数
咖喱Haskell curried和uncurried函数,haskell,functional-programming,Haskell,Functional Programming,咖喱 add::Int->Int->Int add x y = x+y 未结婚 add1::(Int,Int)->Int add1 (x,y)=x+y 我有几个问题重演 CurryE和 unCurrime函数,考虑上面的函数, 问题1 在无载波函数中,输入参数为(Int,Int),那么它是否等同于输入元组?我们如何区分这一点 问题2 关于未结婚和咖喱函数,有哪些利弊?何时以及为什么应该使用哪一种 在无载波函数中,输入参数为(Int,Int),那么它是否等于输入元组?我们如何
add::Int->Int->Int
add x y = x+y
未结婚
add1::(Int,Int)->Int
add1 (x,y)=x+y
我有几个问题重演<强> CurryE和<强> unCurrime函数,考虑上面的函数,
问题1
在无载波函数中,输入参数为(Int,Int)
,那么它是否等同于输入元组?我们如何区分这一点
问题2
关于未结婚和咖喱函数,有哪些利弊?何时以及为什么应该使用哪一种
在无载波函数中,输入参数为(Int,Int),那么它是否等于输入元组?我们如何区分这一点
它不仅是等价的,而且是一个元组。因此,add1
是一个函数,它接受一对整数(2元组),并返回一个整数
关于未结婚和咖喱菜的功能有什么优点和优点,在哪里使用它们
作为一条经验法则,我会说:如果你没有很好的理由不使用curry函数,那么一定要使用curry函数。
它们有一个很好的特性,您可以部分应用它们,例如,您可以编写f=add1
,其中f
现在的类型是f::Int->Int
,并且总是将1添加到其参数中
这有很多应用程序,在Haskell中非常常见,因为它非常方便。例如,向列表中的所有元素添加1的函数将是map(添加1)
此外,语法的噪音要小得多。我喜欢@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
在这两种情况下,我发现无载波函数很有用。幸运的是,在这两种形式之间转换很容易。您也可以通过TH来概括uncurry。使用这种方法的好例子有:“and=foldr(&&&)True”、“or=foldr(| |)False”、“sum=foldl(+)0”、“product=foldl(*)1”、“max=foldl1 max”、“min=foldl1 min”。