Haskell太多的条款,任何替代建议

din*_*sim 11 haskell functional-programming

我在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
Run Code Online (Sandbox Code Playgroud)

再一次,这段代码只是为了说明一个问题,我正在寻找在功能风格中制定问题的方法.你的建议或文章,链接会很有帮助.

谢谢

Dar*_*rio 24

尝试编写抽象的,可重用的函数您将能够更轻松地编写它们

isUnique :: Eq a => [a] -> Bool
isUnique [] = True
isUnique (x:xs) = all (/= x) xs && isUnique xs

noDups :: Eq a => [[a]] -> Bool
noDups = all isUnique
Run Code Online (Sandbox Code Playgroud)


jbe*_*man 6

您不需要第二个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
Run Code Online (Sandbox Code Playgroud)

事实上,这一点要清楚得多,因为在你的版本中,当你绑定xcheckDup,它x仍然在第二个 where子句的范围内,但你将参数绑定checkRow到同一个名称.我认为这可能会让GHC抱怨,这当然令人困惑.