1

Update:

So this is my code:

quadtreeToPic :: Quadtree -> Array (Int, Int) Word8
quadtreeToPic (QNode x y w avg Q0)
  | w == 1 = listArray (0,0) [avg]
  | w == 2 = listArray (0,4) [avg, avg, avg, avg]

quadtreeToPic (QNode x y w avg (Q4 q1 q2 q3 q4)) = listArray ((0,0), (w-1,w-1)) (concat (map quadtreeToPic [q1, q2, q3, q4])) 

A Quadtree is either

QNode Int Int Int Word8 QKids
data QKids = Q0 | Q4 Quadtree Quadtree Quadtree Quadtree

The error I get is

Quadtree.hs:13:90: error:
    • Couldn't match type ‘Array (Int, Int) Word8’ with ‘[Word8]’
      Expected type: [[Word8]]
        Actual type: [Array (Int, Int) Word8]
    • In the first argument of ‘concat’, namely
        ‘(map quadtreeToPic [q1, q2, q3, q4])’
      In the second argument of ‘listArray’, namely
        ‘(concat (map quadtreeToPic [q1, q2, q3, q4]))’
      In the expression:
        listArray
          ((0, 0), (w - 1, w - 1))
          (concat (map quadtreeToPic [q1, q2, q3, q4]))
   |
13 | quadtreeToPic (QNode x y w avg (Q4 q1 q2 q3 q4)) = listArray ((0,0), (w-1,w-1)) (concat (map quadtreeToPic [q1, q2, q3, q4])) 
   |                                                                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

How do I solve this? Why is [[Word8]] expected when by definition it should expect Array (Int, Int) Word8?

5
  • 1
    You probably want to change this to w == 1 = [avg] and w == 2 = [avg, avg, avg, avg], and the type to [Word8], you furthermore probably want to use listArray (hackage.haskell.org/package/array-0.5.3.0/docs/…) instead of array in your quadtreeToPic. Finally I'm not convinced that the logic is completely correct. Commented Jul 30, 2019 at 18:07
  • @WillemVanOnsem I want the type to be ‘Array (Int, Int) Word8’, I was wondering how to return the result in that particular format. I'll look into listArray. Thanks. Commented Jul 30, 2019 at 18:10
  • @WillemVanOnsem your solution w == 1 = [avg] does not use array or listArray though. How would I use it? Commented Jul 30, 2019 at 18:12
  • sorry, I realize you use a recursive approach here. You will need to "unwrap" the arrays in the recursion, or use something that is capable of "combining" two arrays then in the recursive definition. Commented Jul 30, 2019 at 18:13
  • @WillemVanOnsem Your solution solved a lot of the problems. Can you look at my update? Commented Jul 30, 2019 at 18:17

1 Answer 1

4

It's referring to the underlined subexpression:

concat (map quadtreeToPic [q1, q2, q3, q4])
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The expected type is the type that it should be from context, that is:

concat ???

It's what the compiler knows about what ??? must be without looking inside it. concat :: [[a]] -> [a] (*) takes a collection of lists and joins them all together. So we expect to see a collection of lists.

The actual type is the type that it looks like it is when analyzing the expression "from the inside":

map quadtreeToPic [q1, q2, q3, q4]

Here we get, from map and the declared type signature of your function, a [Array (Int,Int) Word8]. It's a collection of arrays. But we were expecting a collection of lists from the previous step. Thus the error:

Couldn't match type ‘Array (Int, Int) Word8’ with ‘[Word8]’

Perhaps you want to turn those arrays into lists using Data.Foldable.toList first?

(*)Well it's actually concat :: Foldable t => t [a] -> [a] but I simplified for exposition.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.