我在Haskell中是全新的,在编写小程序时,我通常最终会有太多where子句来检查函数中的很多东西,所以编写where子句或者还有其他好的替代方法是好的做法吗?
例如,在下面我的代码试图找出是否有二维表的每一行中的蚂蚁重复的元素,它的工作原理以及每一件事情是相同的功能内容,但我不满意的代码看起来如何,我觉得它更迫切接近问题的风格,所以我正在寻找有经验的人在那里的任何建议或想法.
noDups :: [[a]] -> Bool noDups du = and (checkSu du) where checkDup [] = [] checkDup (x:xs) = checkRow x ++ checkDup xs where checkRow [] = [] checkRow (x:xs) = [x /= y | y <- xs] ++ checkRow xs
再一次,这段代码只是为了说明一个问题,我正在寻找在功能风格中制定问题的方法.你的建议或文章,链接会很有帮助.
谢谢
尝试编写抽象的,可重用的函数您将能够更轻松地编写它们
isUnique :: Eq a => [a] -> Bool isUnique [] = True isUnique (x:xs) = all (/= x) xs && isUnique xs noDups :: Eq a => [[a]] -> Bool noDups = all isUnique
您不需要第二个where子句.你可以在同一个where
子句下放置多个函数.同一where
子句中的所有函数名称都在这些函数的主体中.想想顶级功能如何工作.所以你可以写:
noDups :: [[a]] -> Bool noDups du = and (checkSu du) where checkDup [] = [] checkDup (x:xs) = checkRow x ++ checkDup xs checkRow [] = [] checkRow (x:xs) = [x /= y | y <- xs] ++ checkRow xs
事实上,这一点要清楚得多,因为在你的版本中,当你绑定x
时checkDup
,它x
仍然在第二个 where
子句的范围内,但你将参数绑定checkRow
到同一个名称.我认为这可能会让GHC抱怨,这当然令人困惑.