【问题标题】:always return true from guard总是从守卫返回真
【发布时间】:2012-01-12 15:11:16
【问题描述】:

我正在尝试为 99 个 Haskell 问题中的 Problem 27 找出解决方案。
这就是我想要的样子:

  group :: (Eq a) => [Int] -> [[a]] -> [[[[a]]]]
  group []     _  = []
  group (i:is) xs 
    | sum (i:is) /= length xs = error "invalid arguments"
    | otherwise               = ...

链接中的一个例子:

组 [2,2,5] ["aldo","beat","carla","david","evi","flip","gary","hugo","ida"]
[[["aldo","beat"],["carla","david"],["evi","flip","gary","hugo","ida"]],...] (共 756 个解决方案)

因此,我想首先检查 Int 列表的总和是否等于上面的长度 String 列表。我遇到的是,无论这两个值是否相等,它总是打印“无效参数”。我也试过这个:

group (i:is) xs 
     | (sum (i:is) == length xs) = ...
     | otherwise                 = error "invalid arguments"

还是不行
有什么想法吗?

更新:谢谢大家,我的粗心。这是函数的递归部分:

 group (i:is) xs 
     | (sum (i:is) == length xs) = filter (/= []) $ concatGroups (combinations i xs) (group is xs)
     | otherwise                 = error ("invalid arguments: " ++ show (sum(i:is)) ++ "/=" ++ show(length xs))

如您所知,group is xs 减少了总和但不减少长度,因此在递归时它总是会抱怨。我想我会移除那个守卫,并希望用户永远不会做错。

【问题讨论】:

  • 你的group函数是递归的吗?而且,实际上,这是一个坏名字:在Data.List 中存在另一个group 函数。
  • 你能包括其余的功能吗?您可能在 ... 部分的某个地方的递归调用中破坏了不变量。
  • 您可能要求至少一个元素,即组 [1] []。但是第二个列表的长度是多少?第一个的总和是多少?
  • @MatveyB.Aksenov 这个名字来自问题本身,但我实际上并没有使用它

标签: haskell


【解决方案1】:

为了扩展 hammar 的观点,如果您将代码更改为

group :: (Eq a) => [Int] -> [[a]] -> [[[[a]]]]
group []     _  = []
group (i:is) xs 
  | sum (i:is) /= length xs = error ("invalid arguments to group: sum "
                                     ++ show (i:is) ++ " /= " ++ show (length xs))
  | otherwise               = ...

这将帮助您找出... 部分中的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-25
    • 2015-05-16
    • 1970-01-01
    • 1970-01-01
    • 2016-07-31
    相关资源
    最近更新 更多