[英]Understanding the types of functions
我試圖理解函數的類型並能夠解釋它們。
兩個功能:
insert :: t -> Bool -> ([t],[t]) -> ([t],[t])
insert a True (b,c) = (a:b,c)
insert a False (b,c) = (b,a:c)
partition :: (t -> Bool) -> [t] -> ([t],[t])
partition p [] = ([],[])
partition p (x : xs) = insert x (p x) (partition p xs)
從我有限的知識,我認為插入功能:
insert
是t類型,它接受兩個參數bool和兩個類型為t的列表之一,並返回兩個t類型列表的元組。
partition
是類型為t的元組,它返回一個bool,它接受一個類型為t的列表作為參數,並返回兩個類型為t的列表的元組。
這是正確的思考方式還是我弄錯了? 我一直在關注一些教程,這是我到目前為止所理解的。
insert
是t
類型,它接受Bool
兩個參數和兩個類型為t
列表中的一個元組,並返回兩個類型為t
列表的元組。
不 。 首先,它注意到在Haskell每個函數帶一個參數是非常重要的。 確實
insert :: t -> Bool -> ([t],[t]) -> ([t],[t])
是一種簡短緊湊的形式:
insert :: t -> (Bool -> (([t],[t]) -> ([t],[t])))
事實上,上述內容仍然不是很冗長,規范形式如下:
insert :: ((->) t) (((->) Bool) (((->) ((,) ([] t)) ([] t)) ((,) ([] t)) ([] t)))
但上面當然不是很易讀,所以讓我們堅持第二種形式。
Haskell中的每個函數只需要一個參數。 什么這里發生的是應用參數有一定作用的結果 ,產生了新的功能。
因此,如果我們生成一個表達式insert x
,我們構造了一個Bool -> (([t], [t]) -> ([t], [t]))
類型的函數。
非正式地 ,人們確實有時會說“ 函數需要n個參數 ”。 但重要的是要記住這一點。
其次你忘了t
。 我們可以非正式地說insert
有三個參數,一個是t
類型的值,一個boolean(類型為Bool
),一個帶有兩個t
s列表的2元組。 它將返回兩個t
的兩個元組列表。 根據Bool
是True
還是False
它會在兩個列表中添加給定值之一。
例如:
Prelude> insert 5 False ([], [])
([],[5])
Prelude> insert 5 False ([1,4], [2,5])
([1,4],[5,2,5])
Prelude> insert 5 True ([1,4], [2,5])
([5,1,4],[2,5])
Prelude> insert 3 True ([1,4], [2,5])
([3,1,4],[2,5])
Prelude> insert 3 False ([1,4], [2,5])
([1,4],[3,2,5])
partition
是類型為t
的元組,它返回一個bool
,它接受一個類型為t
的列表作為參數,並返回兩個類型為t
列表的元組。
不,這里的參數有一個函數類型(t -> Bool)
。 實際上,在Haskell中,您可以將函數作為參數傳遞。
非正式地,我們可以說partition
采用“ 謂詞 ”(將值映射到Bool
的函數)和t
s列表,並返回帶有兩個t
s列表的2元組。 根據謂詞是否適用於列表中的值,這些值將在2元組的第一個或第二個列表中排序。
例如:
Prelude> partition (>3) [1,4,2,5]
([4,5],[1,2])
Prelude> partition (>3) [1,3,0,2]
([],[1,3,0,2])
Prelude> partition (>3) [1,7,8,0]
([7,8],[1,0])
Prelude> partition (>3) [1,7,8,9]
([7,8,9],[1])
不,類型完全如圖所示:
insert
有類型t -> Bool -> ([t], [t]) -> ([t], [t])
,這意味着它是一個函數,它將t
類型的值作為參數並返回一個函數Bool -> ([t], [t]) -> ([t], [t])
類型Bool -> ([t], [t]) -> ([t], [t])
。 非正式地,您可以insert
視為一個帶有3個參數的函數:一個是t
類型,一個是Bool
類型,另一個是類型([t], [t])
,並返回另一個類型的值([t], [t])
。
partition
是一個函數,它接受另一個函數(類型為t -> Bool
)作為參數,並返回一個類型為[t] -> ([t],[t])
。 非正式地,您可以將partition
視為兩個參數(類型為t -> Bool
和type [t]
)並返回類型([t], [t])
。
->
本身是一個類型級別的運算符; 它需要兩種類型作為參數並返回一個函數類型。 它是右關聯的,這意味着a -> (b -> c)
和a -> b -> c
是等價的。
不, insert
是一個函數 ,所以它不能是“ t
型”。 如果它是t
類型,那么它將是一個值 :
a :: Int
a = 5
這里a
是類型的 Int
。
從函數實現中可以看出, insert
有三個參數:
insert a True (b,c) = ...
參數是a
, True
和(b, c)
。
所以, insert
的類型恰好是t -> Bool -> ([t],[t]) -> ([t],[t])
:
->
s) t
Bool -> ([t],[t]) -> ([t],[t])
類型的另一個函數 Bool -> ([t],[t]) -> ([t],[t])
Bool
類型的參數 (僅限Bool
) ([t],[t]) -> ([t],[t])
([t],[t])
(兩個列表的元組,每個列表都包含某些類型的值t
) ([t],[t])
現在,這看起來像一團糟:函數返回其他返回函數的函數......但這可以簡化。 您可以insert
視為三個參數的函數:
insert
是這個返回其他函數的瘋狂函數:type t -> Bool -> ([t],[t]) -> ([t],[t])
insert 2
是Bool -> ([t],[t]) -> ([t],[t])
類型Bool -> ([t],[t]) -> ([t],[t])
insert 2 True
如果類型為([t],[t]) -> ([t],[t])
insert 2 True ([1], [2])
的類型為([t],[t])
繁榮! 最后一次調用實際上返回了一個值,而不是函數! 因此,可以將insert
視為三個參數的函數。 這個東西叫做currying,它是以Haskell命名的同一個人命名的--Haskell Curry。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.