[英]Nested "where" or "let in" CodeStyle in Haskell
我在 Haskell 中遇到了一些问题:代码风格和大功能(我通过编写玩具语言继续学习 Haskell)。
我有一些必要的大功能(参见示例)。 其中有两个子功能(嵌套在哪里)。 并且没有理由将其子功能放在模块 scope 中。 “Haskell 代码风格”或“Haskell 代码风格最佳实践”如何建议解决“不优雅和笨拙的代码”问题?
Function(后面有评论):
-- 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'
注意事项:
如果你想知道为什么我什至写了这么大的 function 答案是:因为这是一些大的(编译器中需要的功能): - 对于每个“返回变量”,我们应该找到最后一个操作,女巫定义它(实际上对应虚拟寄存器),并使用构造的操作扩展我们的 IR。
我见过一些类似的问题: Haskell 嵌套了 where 子句和“let... in”语法,但它们是关于“如何键入正确的代码?”,而我的问题是“这个代码代码样式是否正确,如果不是” t - 我该怎么办?”。
并且没有理由将其子功能放在模块scope中
反过来想。 有什么理由把子功能放在本地scope中? 然后去做。 这可能是因为
go
助手,它基本上完成了封闭 function 的全部工作。如果这些都不适用,您可以给本地 function 一个描述性名称(正如您已经完成的那样),然后将其放入模块 scope 中。 添加类型签名,使其更清晰。 不要从模块中导出它。
将 function 放入模块 scope 也无需像使用gdefs'
那样重命名变量。 这是 Haskell 代码中的错误的更常见原因之一。
这个问题很好,但示例代码不是一个很好的例子。 对我来说,在这种特殊情况下的正确解决方法是不要谈论如何时尚地嵌套where
s; 它是谈论如何使用库函数和语言特性来简化代码,以至于你不需要首先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'
]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.