簡體   English   中英

Haskell:GHC會對此進行優化嗎?

[英]Haskell : Will GHC optimize this?

GHC可以將id = (\\(a, b) -> (a, b)).(\\(a, b) -> (a, b))簡化為id = \\(a, b) -> (a, b)

更復雜的情況呢?

id (Just x) = Just x
id Nothing = Nothing

map f (Just x) = Just (f x)
map _ Nothing  = Nothing

GHC會簡化id . map id . mapmap

我嘗試使用普通的beta縮減,但看起來這些術語是不可簡化的,因為討厭的模式匹配。

因此,我很好奇GHC的優化技術是如何處理的。

您可以通過使用-ddump-simpl運行它來詢問ghc的這些問題。 這將導致ghc轉儲它編譯程序的“核心”代碼。 Core是編譯器的一部分介於Haskell代碼之間的中間語言,也是編譯器將該代碼轉換為機器代碼的部分。

當我使用-O2 -ddump-simpl編譯以下內容時,結果讓我感到驚訝。

tupid1 :: (a, b) -> (a, b)
tupid1 = (\(a, b) -> (a, b))

tupid2 :: (a, b) -> (a, b)
tupid2 = (\(a, b) -> (a, b)) . (\(a, b) -> (a, b))

由此產生的tupid1核心構成了一個新的專用身份函數。

-- RHS size: {terms: 4, types: 7, coercions: 0}
tupid1 :: forall a_aqo b_aqp. (a_aqo, b_aqp) -> (a_aqo, b_aqp)
[GblId,
 Arity=1,
 Caf=NoCafRefs,
 Str=DmdType <S,1*U(U,U)>m,
 Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,
         WorkFree=True, Expandable=True,
         Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=True)
         Tmpl= \ (@ a_ayd)
                 (@ b_aye)
                 (ds_dIl [Occ=Once] :: (a_ayd, b_aye)) ->
                 ds_dIl}]
tupid1 = \ (@ a_ayd) (@ b_aye) (ds_dIl :: (a_ayd, b_aye)) -> ds_dIl

在核心中,函數的多態類型參數表示為顯式參數。 tupid1為其簽名中的兩個類型變量ab采用其中兩個類型參數,名為a_aydb_aye 它還需要一個術語ds_dIl ,它具有這兩種類型的元組類型( ds_dIl :: (a_ayd, b_aye) )並且不加修改地返回它。

令人驚訝的結果是tupid2 ......

-- RHS size: {terms: 1, types: 0, coercions: 0}
tupid2 :: forall a_aqm b_aqn. (a_aqm, b_aqn) -> (a_aqm, b_aqn)
[GblId,
 Arity=1,
 Caf=NoCafRefs,
 Str=DmdType <S,1*U(U,U)>m,
 Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,
         WorkFree=True, Expandable=True,
         Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=True)
         Tmpl= \ (@ a_axZ) (@ b_ay0) (x_aIw [Occ=Once] :: (a_axZ, b_ay0)) ->
                 x_aIw}]
tupid2 = tupid1

...哪個ghc簡化為tupid1 如何推斷這是超出我的直接知識或發現的能力。


Maybe的標識示例

maybeid :: Maybe a -> Maybe a
maybeid (Just x) = Just x
maybeid Nothing = Nothing

也簡化為沒有模式匹配的身份函數

-- RHS size: {terms: 3, types: 4, coercions: 0}
maybeid :: forall a_aqn. Maybe a_aqn -> Maybe a_aqn
[GblId,
 Arity=1,
 Caf=NoCafRefs,
 Str=DmdType <S,1*U>,
 Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,
         WorkFree=True, Expandable=True,
         Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=True)
         Tmpl= \ (@ a_aqI) (ds_dIq [Occ=Once] :: Maybe a_aqI) -> ds_dIq}]
maybeid = \ (@ a_aqI) (ds_dIq :: Maybe a_aqI) -> ds_dIq

對於這個問題, Maybe map核心並不有意思

maybemap :: (a -> b) -> Maybe a -> Maybe b
maybemap f (Just x) = Just (f x)
maybemap _ Nothing = Nothing

但如果它是由maybeid組成的

maybeidmap :: (a -> b) -> Maybe a -> Maybe b
maybeidmap f = maybeid . maybemap f

ghc將其簡化為maybemap

-- RHS size: {terms: 1, types: 0, coercions: 0}
maybeidmap
  :: forall a_aqp b_aqq.
     (a_aqp -> b_aqq) -> Maybe a_aqp -> Maybe b_aqq
[GblId,
 Arity=2,
 Caf=NoCafRefs,
 Str=DmdType <L,1*C1(U)><S,1*U>,
 Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,
         WorkFree=True, Expandable=True,
         Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=True)
         Tmpl= maybemap}]
maybeidmap = maybemap

如果idf組成,它也會做同樣的事情。

maybemapid :: (a -> b) -> Maybe a -> Maybe b
maybemapid f = maybemap (id . f)

刪除具有身份功能的組合,整個功能簡化為可能maybemap

-- RHS size: {terms: 1, types: 0, coercions: 0}
maybemapid
  :: forall a_aqq b_aqr.
     (a_aqq -> b_aqr) -> Maybe a_aqq -> Maybe b_aqr
[GblId,
 Arity=2,
 Caf=NoCafRefs,
 Str=DmdType <L,1*C1(U)><S,1*U>,
 Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,
         WorkFree=True, Expandable=True,
         Guidance=ALWAYS_IF(arity=2,unsat_ok=True,boring_ok=False)
         Tmpl= \ (@ a_ar2)
                 (@ b_ar3)
                 (f_aqL [Occ=Once!] :: a_ar2 -> b_ar3)
                 (eta_B1 [Occ=Once!] :: Maybe a_ar2) ->
                 case eta_B1 of _ [Occ=Dead] {
                   Nothing -> GHC.Base.Nothing @ b_ar3;
                   Just x_aqJ [Occ=Once] -> GHC.Base.Just @ b_ar3 (f_aqL x_aqJ)
                 }}]
maybemapid = maybemap

暫無
暫無

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

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