2017-09-29 92 views
2

我最近開始通過閱讀LearnYouAHaskell和從互聯網上隨機發表的文章開始學習Haskell。Haskell中的任何類型?

我很難理解更復雜的函數類型。

我明白一些例子。

> :t map 
map :: (a -> b) -> [a] -> [b] 

它需要的功能(這需要一個並給出了B,即A和B可以是不同類型的)和一個公司的名單,並返回b的列表。

> :t fst 
fst :: (a, b) -> a 

獲取2個元素的元組(允許不同類型)並返回第一個元素。

> :t any 

在更高的層次上,我明白了any。它接受一個函數和一個列表,並且如果任何列表條目對於該特定函數返回true,則返回true。我也在Python和JavaScript中使用過它。

問題

  • 我不明白如何any :: Foldable t => (a -> Bool) -> t a -> Bool 翻譯成以上。

    • (a -> Bool)是謂詞。引用一個參數並返回true或false。
    • t a -> Bool布爾是任何的最終結果。根據我的理解t和a表示謂詞和列表。他們爲什麼不通過->
  • 分離如何去一般的理解類型簽名,以及如何深入挖掘,這樣我可以接近他們自己?

回答

11
any :: Foldable t => (a -> Bool) -> t a -> Bool 

這裏Foldable t手段,即t是類型類Foldable的一個實例。

Foldable是一種類,如果類型t是類型類Foldable我們從簽名的t a部分或從類型類Foldable的定義認識的一個實例,即t實際上是一個類型構造。

所以t a是一種類型,因此t a -> Bool是一種函數,它將t a類型的值映射到Bool。這個函數將被關閉,這將 將謂詞應用於類型爲t a的值的每個「元素」,直到它找到一個謂詞,在謂詞下產生True,或者它找不到這樣的元素返回TrueFalse各自的情況。 (實際實現可能會有很大的不同。)

例如,[]是類型爲Foldable的實例,因此t a可能是某種東西的列表。在這種情況下,我們也可以寫[a]而不是[] a

但還有其他類型的構造函數,它們可以是Foldable的實例,例如某些種類的樹。

+0

謝謝。是不是像((方程a)')那樣包含類型類? –

+5

如果只有一個類型類型,可以省略這個paran .. parenth ..函數簽名中的'()'thingies。 – Krom

+1

+1指出'[a]'只是將類型構造函數'[]'應用於類型變量'a'的一種特殊形式,它使用變量'[]'替換字面值'[]',這更容易理解。 – chepner

1

t a不代表謂詞和列表。正如你之前已經正確指出的那樣,(a -> Bool)是謂詞。 t a只是列表,除非它不一定是一個列表(這就是爲什麼它是t a而不是[a])。 t可以是任何可摺疊的,所以它可以是[],但它也可以是其他收藏類型或Maybe

+0

有道理。謝謝 –

10

這可能是有益的注意,until recently, the signature was actually

any :: (a -> Bool) -> [a] -> Bool 

這是在the Foldable Traversable in Prelude proposal概括:現在值的容器不必是一個名單,但可以也可以如一個array

Prelude> import qualified Data.Vector as Arr 
Prelude Arr> :set -XOverloadedLists 
Prelude Arr> let a = [1,2,3] :: Arr.Vector Int 
Prelude Arr> any (>2) a 
True 
+0

第一個簽名很可讀。感謝您指出。 –

2

t a不是由->分開,因爲t a是可摺疊的,前實例:列出一個或樹中。讓我們回到map一秒鐘。你給的版本專門用於列表;更通用的版本(作爲歷史事故,在大多數Haskell版本中稱爲fmap)的類型爲fmap :: Functor f => (a->b) -> f a -> f b。你在這個簽名中的輸入列表在哪裏?這是f a。現在,返回到anyt a是第二個參數,您摺疊的摺疊實例,列表或樹或任何其他參數。

你會讀到Haskell中的所有函數實際上只有1個參數,我們在這裏看到了。 any接受它的第一個參數(謂詞)並返回一個可摺疊的函數(列表,樹等)並返回一個Bool

2

類型簽名是指示要處理的類型以及函數如何部分應用的函數的標記。

Foldable t => (a -> Bool) -> t a -> Bool 

通過Foldable t它首先說any功能可以是可摺疊式的類的實例任何數據類型。

第一個參數(a -> Bool)顯然是一個函數,它從我們的可摺疊數據類型中取單個元素(a),並返回一個Bool類型的值。這是JavaScript中.some(callback)的回調。當您將此參數應用於any時,您將返回一個類型的函數;

t a -> Bool

現在我們留下了一個單一的功能,其僅採用一個參數,並返回一個Bool類型(TrueFalse)值。再次t a是一種數據類型,它是Foldable類型的成員。它可以是[],但也可以是Tree,前提是數據類型的foldMap函數在實例下定義爲Foldable。這是JavaScript的myArr.some(callback)中的myArr部分,只是它不一定是數組。

+0

有道理:-) –