簡體   English   中英

為什么Haskell使用箭頭作為函數的類型?

[英]Why does Haskell use arrows for the type of a function?

我剛剛開始學習Haskell,其中一個奇怪的事情是具有多個參數的函數類型的語法。

考慮一個簡單的例子:

(+) :: Num a => a -> a -> a

為什么我們需要這里的所有箭頭? Num Num Num -> Num會不會更有意義?

引擎蓋下的原因是什么? 我搜索了這個問題,但找不到任何有用的東西。

令人困惑的第一件事是Num a => ,所以我們現在將完全忽略它。 相反,我們考慮Int -> Int -> Int ,這是您給出的類型簽名的一種可能的特化。

功能幾乎都是柯里在Haskell。 這意味着多參數函數實際上是一個參數的函數,它返回一個接受下一個參數的函數,依此類推。

->是右關聯的,因此Int -> Int -> IntInt -> (Int -> Int)是相同的。

這也意味着這個定義

f :: Int -> Int -> Int
f x y = x + y

是相同的

f :: Int -> Int -> Int
f x = \y -> x + y

事實上,Haskell中的所有函數都只有一個參數。 元組也存在,但它們是一等公民,因此它們不僅僅是一個參數列表。

Num a =>是類型系統的一個不同方面。 它表示類型變量a必須是Num類型類的實例。 作為Num實例的類型的常見示例包括IntDouble 所以Num本身不是一個類型,它是一個類型類。 Num a =>表示對類型變量a的約束,它不是該函數的另一個參數。

(+)方法是Num類型類的成員,因此必須以這種方式約束a才能使用(+) 如果你試圖給f簽名a -> a -> a (沒有約束),它將無法工作,因為a完全不受約束,我們對它可以是什么類型一無所知。 結果,我們無法使用(+)

函數類型簽名中每個參數的類型可以包含空格,因此非常需要非空白分隔符,因此編譯器(和人類!)可以區分它們。

例如,您可以擁有參數化的抽象數據類型:

data MyType a = MyValue a

和一個采用具體類型的函數(從MyType類型構造函數構造):

myFunc :: MyType Int -> MyType Int -> String

如果參數之間沒有-> ,則簽名看起來像

myFunc :: MyType Int MyType Int -> String   -- Not valid code

並且編譯器在計算函數的實際參數意圖時會遇到更多麻煩(我想知道在某些情況下它甚至可能是不可能的嗎?)。 至少,它更不容易理解。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM