首页 > 解决方案 > Haskell:无法构造无限类型

问题描述

我得到了一个元组列表(日:月),并想找到天数最多的月份。

我创建了一个函数,它接受我的元组列表和月份列表(或仅 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

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

谢谢。

编辑:这是错误的回溯

标签: haskell

解决方案


您的无限类型源于您maxweekends使用x yand调用的事实x ys。由于类型maxweekends :: Eq b => [(a, b)] -> [b] -> 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获得列表中元素的数量,并将该“月”作为元组的第二项。

x现在我们可以生成一个“argmax” ,它计算f 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

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


推荐阅读