【问题标题】:Haskell: cannot construct the infinite typeHaskell:无法构造无限类型
【发布时间】:2018-10-07 12:22:19
【问题描述】:

我有一个元组列表(日:月),想找出天数最多的月份。

我创建了一个函数,它接受我的元组列表和月份列表(或仅 1 个)来检查并返回指定期间一个月内的最大日期数

maxweekends x [] = 0
maxweekends x [n] = length (filter ((==n).snd) x)
maxweekends x (y:ys) = max (maxweekends x [y]) (maxweekends x ys)

然后我写了一些简单的函数来使用它,但由于“无法构造无限类型”错误而无法编译它。我已经花了几个小时来处理这个错误,但我就是不明白出了什么问题。

func x [] = 0
func x (y:ys)
    | maxweekends x y < maxweekends x ys = func x ys
    | otherwise =  y

理论上它应该调用自己,直到没有日期数量更大的月份,然后才返回答案。

谢谢。

编辑:here is traceback of error

【问题讨论】:

  • 发布完整回溯?
  • 作为一般建议,与其让 GHC 为您推断类型,然后报告不一致,通常最好用显式类型注释顶级绑定。这样,当推断的类型与预期的类型不匹配时,会尽早引发类型错误,这样更容易修复。事实上,大多数 Haskeller 都是从编写函数类型开始编写函数的。

标签: haskell


【解决方案1】:

您的无限类型源于您使用x yx ys 调用maxweekends。由于maxweekends :: Eq b =&gt; [(a, b)] -&gt; [b] -&gt; Int的类型指定给定“第二个”参数是[b]类型,那么第一个参数是[(a, b)]的类型,这意味着x应该是[(a, b)](对于第一次调用) 和[(a, [b])] (用于第二次通话),这是不可能的。

我认为最好先重组这个。让我们首先构造一个如下所示的函数:

groupLength :: Eq b => Int -> b -> [(a, b)] -> Int
groupLength d _ [] = d
groupLength _ x ys = length (filter ((x==) . snd) ys)

因此,对于给定的“月”x,这将获取列表中元素的数量,并将该“月”作为元组的第二项。

现在我们可以生成一个“argmax”,用于计算 xf x 产生的最大值:

argmax :: Ord b => (a -> b) -> [a] -> Maybe (a, b)
argmax _ [] = Nothing
argmax f (x:xs) = Just (go x (f x) xs)
    where go x y [] = (x, y)
          go x y (x2:xs) | y <= y2 = go x y xs
                         | otherwise = go x2 y2 xs
              where y2 = f x2

所以现在只需将groupLength (这是您的maxweekendsargmax 的抽象版本(这或多或少是您的func 所追求的)结合起来)。我离开这个作为练习。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多