简体   繁体   中英

Couldn't match expected type ‘(a0, b0, c0, Geometry -> b)’ with actual type ‘Geometry -> (Int, Int, Int, Int)

I have the following code:

data Geometry = Point Int Int | Circle Int Int Int | Rectangle Int Int Int Int | Triangle Int Int Int Int Int Int | Group [Geometry]

bbox :: Geometry -> (Int, Int, Int, Int)
bbox (Point x y) = (x, y, x, y)
bbox (Circle x y r) = (x - r, y - r, x + r, y + r)
bbox (Rectangle x1 y1 x2 y2) = (x1, y1, x2, y2)
bbox (Triangle x1 y1 x2 y2 x3 y3) = (mx1, my1, mx2, my2)
  where mx1 = min x1 (min x2 x3)
        my1 = min y1 (min y2 y3)
        mx2 = max x1 (max x2 x3)
        my2 = max y1 (max y2 y3)
bbox (Group shape) = (x1, y1, x2, y2)
  where x1 = foldr min 0 [fst bbox s | s <- shape]
        y1 = foldr min 0 [snd bbox s | s <- shape]
        x2 = foldr max 0 [third bbox s | s <- shape]
        y2 = foldr max 0 [fourth bbox s | s <- shape]

Where bbox calculates the bounding box of a given shape.

But I'm getitng the following error:

2.hs:37:34: error:
    • Couldn't match expected type ‘(a0, b0, c0, Geometry -> b)’
                  with actual type ‘Geometry -> (Int, Int, Int, Int)’
    • Probable cause: ‘bbox’ is applied to too few arguments
      In the first argument of ‘fourth’, namely ‘bbox’
      In the expression: fourth bbox s
      In the third argument of ‘foldr’, namely
        ‘[fourth bbox s | s <- shape]’
    • Relevant bindings include y2 :: b (bound at 2.hs:37:9)
   |
37 |         y2 = foldr max 0 [fourth bbox s | s <- shape]
   |                                  ^^^^

I don't get why this error.

Your list comprehensions here contain an error:

foldr min 0 [ | s <- shape]

Here fst is applied to bbox . It thus expects a 2-tuple, but you pass it a function bbox :: Geometry -> (Int, Int, Int, Int) . Note that fst only works on 2-tuples, not on 4-tuples.

You can use a let expression for example to "unpack" the 4-tuple:

foldr min 0 [ | s <- shape, let  = bbox s]

You should fix the other expressions in a similar way.

Note that you can use minimum here, and implement this as:

minimum [x | s <- shape, let (x,_,_,_) = bbox s]

or if you implemented your own functions to operate on 4-tuples, you can write this as:

-- …
bbox (Group shapes) = (x1, y1, x2, y2)
  where x1 = minimum (0:map myfirst bbs)
        y1 = minimum (0:map mysecond bbs)
        x2 = maximum (0:map mythird bbs)
        y2 = maximum (0:map myfourth bbs)
        bbs = map bbox shapes

I'm not sure however that prepending with zero is a good idea. It means that (0,0) will always be part of the bounding box of a Group ? Regardless what elements are in te group? You might want to use a NonEmpty to ensure that the Group contains at least one element.

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