1
votes

I'm working through 99 Problems in Haskell and running into a type issue I cannot resolve. I was using a wrapper function to solve the problem on my first attempt.

The goal

Pack consecutive duplicates of list elements into sublists. If a list contains repeated elements they should be placed in separate sublists.

Example:

Main> pack ['a', 'a', 'a', 'a', 'b', 'c', 'c', 'a', 'a', 'd', 'e', 'e', 'e', 'e']
["aaaa","b","cc","aa","d","eeee"]

My code:

pack :: (Eq(a)) => [a] -> [[a]]
pack [] = []
pack xs = pack' ((filter (== head xs) xs):[]) (filter (/= head xs) xs)

pack' :: (Eq(a)) => [[a]] -> [a] -> [[a]]
pack' xs [] = xs
pack' xs ys = ((filter (== head ys) ys):xs) (filter (/= head ys) ys)

So when I run this, I have trouble with the 7th line and get the following debugger output:

09.hs:7:15:
    Couldn't match expected type `[a0] -> [[a]]'
                 with actual type `[[a]]'
    The function `(filter (== head ys) ys) : xs'
    is applied to one argument,
    but its type `[[a]]' has none
    In the expression: ((filter (== head ys) ys) : xs) (filter (/= head ys) ys)
    In an equation for pack':
        pack' xs ys = ((filter (== head ys) ys) : xs) (filter (/= head ys) ys)
Failed, modules loaded: none.

I just do not see where the extra [a0] -> [[a]] is coming from.

Prelude> let b = [5,3,4,5,3,2,3,4,5,6]
Prelude> (filter (== head b) b):[]
[[5,5,5]]
Prelude> (filter (== head b) b):[[4,4]]
[[5,5,5],[4,4]]

Something is going over my head. Could someone explain what I am missing?

2
pack is same as group from Data.List - Satvik
Correct, I am just working through solving some exercises. I wanted to do it w/o only renaming the function. - kealist
group groups only consecutive duplicates, fyi. - kqr
Thank you for the correction of my incorrect correction @kqr - kealist
@kqr Isn't that what pack is doing here? - Satvik

2 Answers

3
votes

This seventh line is a little weird:

((filter (== head ys) ys):xs) (filter (/= head ys) ys)

What it says is:

  1. Take the function given by

    ((filter (== head ys) ys):xs)
    
  2. and call it with the argument

    (filter (/= head ys) ys)
    

which is probably not at all what you intended. This becomes more clear if you replace the expressions with names, like the following equivalent expression:

let func = ((filter (== head ys) ys):xs)
    arg  = (filter (/= head ys) ys)
in  func arg

Did you miss to put something between the two expressions? Keep in mind that arg in this case is [a] while func is [[a]]. I think you meant to say

func : [arg]

but I'm not sure, because I don't know what you are trying to accomplish.

1
votes

The expression pack' xs ys = ((filter (== head ys) ys):xs) (filter (/= head ys) ys) contains the error. The subexpression ((filter (== head ys) ys):xs) is being used as a function with (filter (/= head ys) ys) as its argument. However, ((filter (== head ys) ys):xs) has type [[a]], since filter (== head ys) ys returns a value of type [a], and it is appended onto the front of xs, which is of type [[a]].

What is the expected return value for pack'? Could you provide an example that would demonstrate its behavior?