簡體   English   中英

這些明確的“forall”在做什么?

[英]What are these explicit “forall”s doing?

這段代碼中forall的目的是什么?

class  Monad m  where
    (>>=)       :: forall a b. m a -> (a -> m b) -> m b
    (>>)        :: forall a b. m a -> m b -> m b
        -- Explicit for-alls so that we know what order to
        -- give type arguments when desugaring

(省略了一些代碼)。 這來自Monads的代碼。


我的背景:我真的不了解forall或Haskell隱含地擁有它們。

此外,它可能並不重要,但GHCi允許我在給出>> a類型時省略forall

Prelude> :t (>>) :: Monad m => m a -> m b -> m b
(>>) :: Monad m => m a -> m b -> m b
  :: (Monad m) => m a -> m b -> m b

(沒有錯誤)。

我的背景:我真的不了解forall或Haskell隱含地擁有它們。

好的,考慮id的類型, a -> a 這是什么a平均值,它從何而來? 定義值時,不能只使用未在任何位置定義的任意變量。 您需要頂級定義,函數參數或where子句,&c。 通常,如果使用變量, 則必須將其綁定到某處。

類型變量也是如此, forall是綁定類型變量的一種方式。 任何地方,你看到沒有明確的約束(例如,一個類型變量class Foo a where ...結合a ,它隱含一個綁定的類定義中) forall

所以, id的類型是隱含的forall a. a -> a forall a. a -> a 這是什么意思? 幾乎就是這么說的。 我們可以得到一個類型a -> a 為所有可能的類型a ,或者從另一個角度來看,如果你選擇的任何特定類型,你可以得到代表“從你所選擇的類型函數本身”一類。 后面的措辭聽起來有點像定義一個函數,因此你可以認為forall類似於lambda抽象類型。

GHC在編譯期間使用各種中間表示,並且它應用的一個轉換是使函數的相似性更直接:隱式forall是明確的,並且在多態值用於特定類型的任何地方,它首先應用於類型爭論

我們甚至可以將forall和lambdas都寫成一個表達式。 我會暫時濫用記譜法並替換forall a. 使用/\\a =>以獲得視覺一致性。 在這種風格中,我們可以定義id = /\\a => \\(x::a) -> (x::a)或類似的東西。 因此,代碼中的id True的表達式最終將轉換為id Bool True ; 只是id True不再有意義。

正如您可以重新排序函數參數一樣,您也可以重新排序類型參數,僅受限於類型參數必須在該類型的任何值參數之前出現的(相當明顯的)限制。 由於隱式forall始終是最外層,因此GHC可能會在明確表示時選擇所需的任何順序。 一般情況下,這顯然無所謂。

我不確定在這種情況下到底發生了什么,但根據評論我會猜測,在某種意義上,使用顯式類型參數的轉換和do notation的貶值是彼此不了解的,因此明確指定類型參數的順序以確保一致性。 畢竟,如果某些東西盲目地將兩個類型的參數應用於表達式,那么該表達式的類型是否為forall a b. ma -> mb -> mb是很重要的forall a b. ma -> mb -> mb forall a b. ma -> mb -> mbforall b a. ma -> mb -> mb forall b a. ma -> mb -> mb

暫無
暫無

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

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