Understanding arguments in Haskell type classes and instances

I am trying to understand a Haskell class declaration and instance from a paper. I am trying to understand the class declaration:

class (Surfaces v o, Paths a b (v o)) => Vehicles v o a b


My current understanding is that the first occurance of types "v o" in the Vehicles context seems to refer to two distinct data types. I assume that it is the same for the "v o" on the right of =>.

Question 1

Is my understanding correct? Does the bracketed "(v o)" in the Vehicles context refer a type constructor and its argument, rather than two independent types?

Question 2:

Is the instance OK? Why do I need FlexibleInstances

 instance Vehicles Boat Person Route (Water Source)


I apologize for the level of detail, but I believe that the context is important to my question. Regards, Pat

{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
data Person = Person deriving Show
data House a = House a  deriving Show
data Boat a  = Boat a deriving Show
data Route a b = Route a b deriving Show
data Source = Source deriving Show
data Destination = Destination deriving Show
data Water a = Water a deriving Show
data Land = Land deriving Show

-- The three top level classes are constructor classes, indicated by the signatures of the methods (not the class header).
-- The kinds in the class headers have kinds * and *->*
-- "Containers a b" stands for all container types "a" holding things of type "b".
class Containers a b where
insert :: b -> a b -> a b
remove :: b -> a b -> a b
whatsIn :: a b -> [b]

-- Type "a" is the type of  surface
-- Type "b" is the type object on the surface e.g. boat is on water.
class Surfaces a b where
put :: b -> a b -> a b
takeOff :: b -> a b -> a b
whatsOn :: a b -> [b]

-- The path class represents motion
-- Type "c" represents the moving object e.g Boat.
-- Type "a" route
-- Type "b" origin and destination place
class Paths a b c where
move :: c -> a b c -> a b c
origin, destination :: a b c -> b
whereIs :: a b c -> c -> b

class People p
class Surfaces w o => WaterBodies w o
class Containers h o => Houses h o

-- The types "v o" in the Vehicles the context seems to refer to two distinct data types.
-- I assume that it is the same for the "v o" on the right of =>
-- But "(v o)" in the Vehicles the context seems to refer a type constructor and its argument??.
-- Vehicles are derived from surfaces (affording to ride on the vehicle) and paths (affording motion).
-- Vehicles type class has  parameters for
--  the type "o" of the transported object
--  the type "a" of the path,
--  the type "b" of the origin and destination places.
--  "o" has kind *, "a" has kind *->*->*,  "v" has kind *->*
class (Surfaces v o, Paths a b (v o)) => Vehicles v o a b

instance Surfaces Boat Person
instance WaterBodies Boat Person  -- Boats carrying people on water
instance Paths Route (Water Source) (Boat Person) -- boat moving on water carrying people
instance Vehicles Boat Person Route (Water Source)  -- Boat as a vehicle


Question 1

Does the bracketed "(v o)" in the Vehicles context refer a type constructor and its argument, rather than two independent types?

In the constraint Surfaces v o, v and o are two separate type arguments to class Surfaces. Constraint Paths a b (v o) has three arguments: a, b, (v o). The third is v applied to o, so we can infer parameter v to class Vehicles is a type constructor, kind * -> *.

I'm not sure what you're trying to say by "independent types": v, o, are distinct parameters to Vehicles. The constraints are telling us we can't freely choose just any types for a, b, v, o, so they're all inter-dependent.

Question 2:

Is the instance OK? Why do I need FlexibleInstances

   instance Vehicles Boat Person Route (Water Source)


Firstly, class Vehicles needs FlexibleContexts. That's because not all of the constraints are of the form class name followed by bare type variables. Argument (v o) is the culprit.

Similarly for that instance, not all the type arguments are plain type constructors or constructors followed by bare type vars. Argument (Water Source) is the culprit. If it were (Water b), that wouldn't need FlexibleInstances.