简体   繁体   中英

Haskell: cannot construct the infinite type

I got a list of tuples (day:month) and want to find the month with the biggest amount of days.

I made a function that accepts my list of tuples and list of months (or just 1) to check and returns the maximum amount of dates in one month in specified period

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

Then I wrote some simple function to use it, but I cant compile it because of "cannot construct the infinite type" error. I already spent a few hours with this error but I just cant understand what is wrong.

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

In theory it should call itself until there is no month with bigger amount of dates and then just return answer.

Thanks.

Edit: here is traceback of error

Your infinite type arises from the fact that you call maxweekends with xy and x ys . Since the type of maxweekends :: Eq b => [(a, b)] -> [b] -> Int specifies that given the "second" parameter is of type [b] , then the first parameter is a type of [(a, b)] , this means that x should be [(a, b)] (for the first call) and [(a, [b])] (for the second call) at the same time, which is impossible.

I think it might be better to first restructure this. Let us first construct a function that looks like:

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

This will thus for a given "month" x obtain the number of elements in the list with as second item of the tuple that "month".

Now we can generate an "argmax" that calculates for which x , fx produces a maximum value:

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

So now it is only a matter of combining the the groupLength (which is an abstract version of your maxweekends with argmax (which is more or less what your func is after). I leave this as an exercise.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM