簡體   English   中英

類型統一/函數應用程序如何在 Haskell 的高層次上工作?

[英]How does type unification/function application work at a high level in Haskell?

我覺得我並沒有真正了解函數應用程序是如何工作的,或者我可能正在關注一些我不應該做的事情。

讓我們嘗試確定(fmap .)的類型簽名

fmap :: (x -> y) -> fx -> fy

(.) :: (b -> c) -> (a -> b) -> a -> c -- signatures taken from GHC

fmap應用於(.) ,我們本質上想讓(x -> y) -> fx -> fy(b -> c)相等。 當我第一次嘗試這樣做時,我記得有一段非常艱難的時光。 您必須將一組 4 個變量與一組 2 個變量相匹配,所以顯然您必須進行一些分組,但是如何? 我看到了 3 種可能的解決方案,它們都有效嗎? 還是只有1? 我讀到編譯器並沒有真正考慮括號,所以我們最終得到x -> y -> fx -> fyb -> c ,還有與右邊相關的函數,所以fmap實際上應該看起來像x -> (y -> (fx -> fy)) ,這導致我

b = x

c = y -> fx -> fy

導致(a -> x) -> (a -> y -> fx -> fy)作為(fmap .)的簽名。

我已經看到解決這個問題的分組是(a -> b) -> (fa -> fb) 所以

b = x -> y

c = fx -> fy

導致(a -> x -> y) -> a -> fx -> fy ,這與 GHC 的(a1 -> a2 -> b) -> a1 -> f a2 -> fb if 或多或少相同你重命名一些類型變量。

現在比較兩個結果,去掉括號:

a -> x -> a -> y -> fx -> fy

a -> x -> y -> a -> fx -> fy

我們可以清楚地看到第 3 和第 4 個參數類型是切換的,這意味着它們顯然不一樣,因為flip是一個東西。 這意味着這個替換

b = x

c = y -> fx -> fy

無效。 還是我錯過了什么?

我有一種感覺,當我應該反過來做時,我正試圖根據簽名使函數工作。 :t fmap 'c'失敗, Couldn't match expected type 'a -> b' with actual type 'Char'這意味着您不能真正部分應用fmapa -> b部分。 您只能部分應用fmap本身,我猜它的第一個參數是不可分割的。 我不知道我是否得到了這一切背后的模式。

我真的應該嘗試編寫一個類型化的 lambda 演算。

我看到了 3 種可能的解決方案,它們都有效嗎?

不。

還是只有1?

只有一個。 (x -> y) -> fx -> fy等於(x -> y) -> (fx -> fy)並且僅是因為->是右結合的。 把括號放在其他點是錯誤的。

我讀到編譯器並沒有真正考慮括號,

那是假的。 編譯器隱含地工作,因為括號總是以右關聯方式添加:類型a -> b -> c -> d僅作為a -> (b -> (c -> d))處理。 相比之下,類型(a -> b) -> c -> d僅被處理為(a -> b) -> (c -> d) ,類型(a -> b -> c) -> d僅作為(a -> (b -> c)) -> d處理。

所以我們最終得到x -> y -> fx -> fyb -> c

不,那是錯誤的,你必須保留括號。 我們必須滿足類型相等

(x -> y) -> (f x -> f y)
~
b -> c

唯一的解決方案是

b ~ (x -> y)
c ~ (f x -> f y)

正如你后來發現的那樣。

要了解統一中發生了什么,我認為如果您從以右關聯方式添加隱式括號開始是有益的。 如果你這樣做,你可以忘記像a -> b -> c這樣的類型,而只關心基本情況(T -> U)及其統一步驟:

from (T1 -> U1) ~ (T2 -> U2)
deduce T1 ~ T2 and U1 ~ U2

暫無
暫無

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

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