我在 Haskell 中遇到了一些問題:代碼風格和大函式(我繼續通過撰寫玩具語言來學習 Haskell)。
我有一些必要的大功能(參見示例)。其中有兩個子函式(嵌套在何處)。并且沒有理由將其子功能放在模塊 scope 中。“Haskell code-style”或“Haskell code-style best practice”如何解決這個“不優雅和笨拙的代碼”的問題?
功能(后附評論):
-- We can delete (on DCE) any useless opers.
-- Useful opers - only opers, whitch determine (directly or transitivery) result of GlobalUse oper
addGlobalUsageStop :: [Var] -> IR -> IR
addGlobalUsageStop guses iR = set iOpers (ios ios') $ set opN opn' iR
where
ios = _iOpers iR
gdefs = _gDefs iR :: M.Map Int Var
opn = _opN iR
guses' = nub $ filter isRegGlobal guses
ogs = catMaybes $ map (concatIOperWithGDef gdefs) $ reverse ios
where
concatIOperWithGDef gdefs' (i, o) = case gdefs' M.!? i of
Nothing -> Nothing
Just gd -> Just (o, gd)
nops = newGUses ogs guses'
where
newGUses [] _ = []
newGUses _ [] = []
newGUses ((Oper _ d _ _, g):os) guses = if elem g guses
then (Oper GlobalUse g (RVar d) None):newGUses os (filter (g /=) guses)
else newGUses os guses
ios' = zip [opn..] nops
opn' = opn length ios'
注意事項:
如果你想知道為什么我什至寫了這么大的函式,答案是:因為這是編譯器中一些大的(并且是編譯器中需要的功能): - 對于每個“回傳變數”,我們應該找到最后一個操作,女巫定義它(實際上對應虛擬暫存器),并用構造的操作擴展我們的 IR。
我見過一些類似的問題:Haskell 嵌套了 where 子句和“let ... in”語法, 但它們是關于“如何打字正確的代碼?”,以及我的問題“這段代碼代碼風格是否正確,如果不是” t - 我該怎么辦?”。
uj5u.com熱心網友回復:
并且沒有理由將其子功能放在模塊范圍內
反過來想想。是否有任何理由將子功能放在本地范圍內?然后去做。這可能是因為
- 它需要訪問本地系結變數。在這種情況下,它必須是本地的,否則您需要額外的引數。
- 它做了一些非常明顯且僅與特定用例相關的事情。這可能是某些操作的單行定義,您不關心是否考慮了正確的描述性名稱,或者它可能是一個
go基本上完成封閉函式全部作業的助手。
如果這些都不適用,并且您可以為本地函式指定一個描述性名稱(正如您已經完成的那樣),然后將其放入模塊范圍內。添加型別簽名,使其更加清晰。不要從模塊中匯出它。
將函式放在模塊范圍內還消除了像使用gdefs'. 這是 Haskell 代碼中錯誤的更常見原因之一。
uj5u.com熱心網友回復:
這個問題很好,但示例代碼不是一個很好的示例。對我來說,在這種特殊情況下的正確解決方法不是談論如何時尚地嵌套wheres;它是談論如何使用庫函式和語言功能來簡化代碼,以至于您where首先不需要。特別是,串列推導式可以讓您走得更遠。以下是我將如何撰寫這兩個定義:
import Data.Containers.ListUtils (nubOrdOn)
... where
ogs = [(o, gd) | (i, o) <- reverse ios, Just gd <- [gdefs M.!? i]]
nops = nubOrdOn fun
[ Oper GlobalUse g (RVar d) None
| (Oper _ d _ _, g) <- ogs
, g `elem` guses'
]
fun (Oper _ g _ _) = g -- this seems useful enough to put at the global scope; it may even already exist there
由于ogs未在代碼中的其他任何地方提及,您可以考慮行內它:
-- delete the definition of ogs
nops = nubOrdOn fun
[ Oper GlobalUse g (RVar d) None
| (i, Oper _ d _ _) <- reverse ios
, Just g <- [gdefs M.!? i]
, g `elem` guses'
]
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/398721.html
