我很難理解型別宣告是如何作業的......例如這些:
t :: (a -> b) -> (b -> c) -> a -> c
s :: (a -> b -> c) -> (a -> b) -> a -> c
我從嘗試不同的事情中知道正確的功能應該是這樣的:
t :: (a -> b) -> (b -> c) -> a -> c
t f g x = g (f x)
s :: (a -> b -> c) -> (a -> b) -> a -> c
s f g x = f x (g x)
但這是如何作業的?為什么括號在最后?為什么不是
t f g x = (f x) g
或者
s f g x = (f x) g x
我很迷茫
uj5u.com熱心網友回復:
對于第一個示例:
t :: (a -> b) -> (b -> c) -> a -> c
在型別宣告中,type1 -> type2模式表示從type1到的函式type2。在型別宣告中,->運算子是右關聯的,所以它被決議為:
t :: (a -> b) -> ((b -> c) -> (a -> c))
這種構造稱為“currying”:提供第一個引數(type a -> b)產生一個接受第二個引數(type b -> c)的函式,該函式產生一個接受第三個引數(type a)的函式。
函式宣告語法設定為自動執行此操作。前兩個引數是函式,第三個是 just a,所以從反映這一點的名稱開始: f :: a -> bandg :: b -> c是函式,whilex :: a是一個完全通用的型別,可以是任何東西。
t f g x = ...
請注意,Haskell 中的函式應用只是串聯:要將函式f應用于 value x,只需使用f x. 此語法是左關聯的,因此t f g x被決議為(((t f) g) x)與上述柯里化構造相匹配。
無論如何,鑒于這些型別,您在如何將它們組合在一起方面沒有太多選擇:
關于型別,你唯一知道的
a是它的型別x和引數型別f,所以你唯一能用它們做的就是將函式應用于值:f x。你唯一知道的型別
b是它的結果型別f和引數型別g,所以你唯一能做的就是應用g (f x)。關于型別,你唯一知道的
c是它是g整個函式的結果型別和t,所以唯一t可以回傳的是g (f x).
你不能做的原因(f x) g是型別不匹配:
f :: a -> b
x :: a
(f x) :: b
g :: b -> c
因此,您可以申請g :: b -> c獲得(f x) :: btype 的結果c。但不是相反,因為b可能甚至不是函式型別。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/528517.html
標籤:哈斯克尔类型
上一篇:如何手動實作Show實體?
