【问题标题】:Non-exhaustive patterns in haskell, created data typehaskell 中的非详尽模式,创建的数据类型
【发布时间】:2019-10-12 23:26:49
【问题描述】:

我在这里第 2 行的代码中得到了一个非详尽的模式,我认为它具有侵入性,因为我需要它让我的递归在某个时候停止。 它说模式不匹配:[] _

allergyFree :: [Ingredient] -> [Cupcake] -> [Cupcake]
allergyFree (y:ys) [] = []
allergyFree (y:ys) (c:cs) = if(not(igPresent (y:ys) recipeN)) then ([c] ++ (allergyFree (y:ys) cs))
                            else (allergyFree (y:ys) cs)

where
CC (P priceN) recipeN = c
igPresent :: [Ingredient] -> [Ingredient] -> Bool
igPresent [] recipeN = False
igPresent (y:ys) recipeN = if (y `elem` recipeN) then True
                           else igPresent ys recipeN

任何帮助将不胜感激!

附:我对haskell很陌生

【问题讨论】:

  • 问题:当您拨打allergyFree [] _somethingelse 时会发生什么?这是您的非详尽模式。
  • 是的,我会出错,我意识到出了什么问题,并明确定义了所有列表为空的情况,谢谢!
  • 我希望这可以写得更简洁;例如类似allergyFree allergies = filter (\(CC _ recipe) -> all (`notElem` recipe) allergies)。这种方式对我来说似乎也很可读。
  • 使用-Wall 启用警告。如果您这样做了,GHC 会就您未能处理的案例向您发出警告。

标签: haskell


【解决方案1】:

(y:ys) 仅匹配非空列表 - 它指的是具有第一个元素 y 的列表(而 ys 指的是列表的其余部分)。由于您的两个模式的第一个参数都有(y:ys),因此如果您尝试在该位置传递一个空列表,该函数将失败并出现此错误。

我只是简单地浏览了您的代码,但是由于您没有在函数定义中的任何位置单独使用 yys 变量,因此如果您将 (y:ys) 模式替换为单个命名,例如 x,然后在当前定义中包含 (y:ys) 的任何位置使用 x

【讨论】:

  • 谢谢!而不是这样做,我只是定义了两个列表都为空的所有情况;明确的;因为我想使用 x 和 xs 而不想使用 head 和 tail 函数
【解决方案2】:

当你对两个列表进行模式匹配时,你必须在两种情况下都添加空列表的模式(如果你希望你的函数是总的):

allergyFree :: [Ingredient] -> [Cupcake] -> [Cupcake]
allergyFree _ [] = [] -- second list is empty, I don't care about the first
allergyFree [] _ = [] -- first list is empty, I don't care about the second
allergyFree (y:ys) (c:cs) = -- logic when both has elements

【讨论】:

    猜你喜欢
    • 2019-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多