[英]type signature of uncurry function
uncurry f=\(a,b)->f a b
uncurry
將uncurry
函數轉換為對上的函數,但上面的函數只是將它轉換為curried函數fab
。 這與uncurry
函數的定義是否相矛盾?
什么樣的人和Chuck說的是100%正確的。 我認為你在某些方面對咖喱與不良和功能定義有點混淆。
我們知道一個curried函數是這樣的:
add xy = x + y
它的定義是:
add :: (Num a) => a -> a -> a
Add接受Num
,並返回一個帶Num
並返回Num
的函數 。
通過這種方式,我們可以得到一個部分應用的功能,如
add3 = add 3
感謝add
curried,當我們只傳遞一個參數(在本例中為3)時,我們可以返回一個帶Num
並返回Num
的函數。
>add3 5
8
未計算的函數采用元組 ,或將值組合在一起,如(1,2)。 (注意,元組不需要配對。你可以有一個(1,2,3,4,5)形式的元組。只是常規的舊的uncurry處理特定的對)。 如果我們改變了我們的添加不被證實,它將是:
add :: (Num t) => (t, t) -> t
add (x, y) = x + y
這需要兩個Num
s的元組並返回Num。 我們不能像使用添加作為curried函數那樣部分地應用它。 它需要兩個參數,在元組中傳遞。
現在,進入uncurry功能! (如果您想知道函數的類型,請在GHCi中使用:t <some function>
,或使用Hoogle )。
uncurry :: (a -> b -> c) -> ((a, b) -> c)
uncurry f=\(a,b)->f a b
那么我們從中得知什么呢? 這需要F,其從我們的定義中注意到的是從(A-> B-> c)一種咖喱功能,並且它返回一個uncurried函數 ((A,B) - > C)。
如果我們提供不合格的咖喱添加(記住: add xy
),我們會得到什么?
我們得到一個帶有元組的匿名函數或lambda函數,並將元組a
和b
的值應用於我們的函數add
。
fab
並不意味着我們得到一個功能 - 你會看到->
如果是這樣的話。 我們只用a
和b
得到f
的值 。
這有點像我們手工做到這一點:
tupleAdd (a,b) = add ab
但是,對於我們來說, uncurry
,我們可以繼續使用我們最初的咖喱功能的全新形式。
很酷,嗯?
編寫這個定義的另一種方式是使得更清楚的是:
uncurry :: (a -> b -> c) -> (a, b) -> c
uncurry f = \(a, b) -> (f a) b
變量f
類型為a -> b -> c
,即它是一個uncurry g
函數,對於某些uncurry g
函數g
, uncurry g
g
具有類型(a, b) -> c
,即一個未計算的函數。
請記住,當x
和y
是術語時, xy
表示將函數x
應用於y
。 而fab
(或(fa) b
)表示將函數f
應用於參數a
,生成類型為b -> c
函數,然后立即將此函數應用於b
,生成類型為c
的結果 。 所以這個定義的右邊只是展示如何解壓縮元組參數的組件並將它們應用於curry函數,這正是uncurrying的過程!
您可以編寫一個函數,其行為方式相同(並且具有相同的簽名),而不使用lambda:
uncurry' :: (a -> b -> c) -> ((a, b) -> c)
uncurry' f (a,b) = f a b
我認為這個版本更容易閱讀。 如果你有一個tupel和一個函數,它接受兩個單獨的值(或者更確切地說,它取一個值並返回一個接受下一個值的函數),那么uncurry'函數會為我們“解包”元組。
一般來說,如果你看到像
f x y z = x + y + z
它是一樣的
f = \x y z -> x + y + z
要么
f x = \y -> (\z -> x + y + z)
我覺得你誤讀了。 它確實在對上返回一個函數。 這就是\\(a,b)->
部分的含義 - 它定義了一個匿名函數,該函數接受一對並對該對中的值執行給定函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.