Haskell type classes as ontological categories A paper uses Haskell type classes to represent ontological categories.
A type class hierarchy is used to represent &quot;concept hierarchies&quot; where &quot;functions are the units of inheritance&quot;. Here is a diagram of the Haskell type classes based on the paper:

With respect to the code below the following claim is made:

The Haskell code given so far is complete and type checked, explaining
the entire refined concept hierarchies. With instantiations for types
of boathouses and houseboats, values can be declared and axioms stated
and evaluated to demonstrate semantic properties and differences. For
example, it can be shown that a passenger on a boat in a boathouse
cannot be said to be an inhabitant, while a passenger on a houseboat
can.

The spatial prepositions in and on form part of the semantics the whatsIn and whatsOn predicates in the code below.
I have a three  questions:
(Q1) Is the claim true?
(Q2) How would go about validating such a claim.
As regards Q2, I have create 72 instances with appropriately kinded data types   as advised by the GHCI compiler (not supplied in this post).
Then I checked the types with the following type level queries

Query 1 :  A passenger on a boat in a boathouse cannot be said to be
in the boathouse  (i.e. an inhabitant)

:t whatsIn (BoatHouse (Boat People)) =t=&gt; OK whatsIn (BoatHouse (Boat People)) :: [Boat People]
:t whatsOn (HouseBoat  People) =t=&gt; ERROR  No instance for (Surfaces BoatHouse (Boat People))


Query 2 : A person can be both on and in a houseboat (a passenger and an inhabitant).

whatsOn (HouseBoat  People) :: [People]
:t  whatsIn (HouseBoat  People)  =t=&gt; whatsIn (HouseBoat  People) :: [People]
:t  whatsOn (HouseBoat  People) =t=&gt; whatsOn (HouseBoat  People) :: [People]

(Q3) Both these queries seem to be apptropriately accepted and rejected by Haskell. Is there a better or easier way to validate this claim?
Listing 1 shows the source code from paper.
class Containers a b where
 insert :: b -&gt; a b -&gt; a b
 remove :: b -&gt; a b -&gt; a b
 whatsIn :: a b -&gt; [b]


class Surfaces a b where
 put ::  b -&gt; a b -&gt; a b
 takeOff :: b -&gt; a b -&gt; a b
 whatsOn :: a b -&gt; [b]


class Paths a b c where
 move :: c -&gt; a b c -&gt; a b c
 origin, destination :: a b c -&gt; b
 whereIs :: a b c -&gt; c -&gt; b

class PeopleClass p
class HeavyLoads l
class Surfaces w o =&gt; WaterBodies w o
class Containers h o =&gt; Houses h o
class (Surfaces v o, Paths a b (v o)) =&gt; Vehicles v o a b
class (Vehicles v o a b, WaterBodies w (v o)) =&gt; Vessels v o a b w
class (Vessels v p a b w, PeopleClass p) =&gt; Boats v p a b w
class (Boats v p a b w, HeavyLoads p) =&gt; Barges v p a b w
class (Houses h (v p), Boats v p a b w, Contacts w (h (v p))) =&gt; BoatHouses h v p a b w
class (Barges v p a b w, Houses v p, PeopleClass p) =&gt; HouseBoats v p a b w
The code in Listing 1 represents my attempt to test the claim. I have simplified the classes, while retaining that ability to test the original claim, which is repeated here:
The Haskell code given so far is complete and type checked, explaining the entire refined concept hierarchies. With instantiations for types of boathouses and houseboats, values can be declared and axioms stated and evaluated to demonstrate semantic properties and differences. For example, it can be shown that a passenger on a boat in a boathouse cannot be said to be an inhabitant, while a passenger on a houseboat can.
Here is the simplified class hierarchy:

If we interpret an inhabitant as being directly in the boathouse then the claim is somewhat reasonable. This is because in Listing 1 whatsIn is not defined for type BoatHouseD, attempting to evaluate in GHCi:
whatsIn (BoatHouseDc (PeopleDc &quot;joe&quot;)) 

will cause error. In general, if a function is not defined for a data type that function will fail to type check. Note whatsIn is defined in an instance of ContainersC class for the type BoatD  and also defined in an instance of ContainersC class for the type BoatHouseD.  whatsOn  is defined for an instance of SurfacesC. These functions cannot be defined in the sub-classes  HousesC, BoatHousesC, and HouseBoatsC of ContainersC or BoatsC, BoatHousesC, and HouseBoatC of SurfacesC.
On the other hand the semantics of the Haskell code can be used to refute the claim. The test in Listing 1 shows that if someone is on a boat and that boat is in a boathouse then they are indirectly in the boathouse.
Conclusion
Based on the Haskell code in Listing 1 we can refute the claim. Reasoning about the Haskell code there is some credibility in the claim. The sub-classes seem to be redundant, because functions can only be defined in instances of the class where they were originally declared, not in any sub-class of that original class. So the functions whatsIn and whatsOn cannot be defined for the sub-classes.
Listing 1
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-#  OPTIONS_GHC  -Wno-missing-methods #-}
 -- The suffix D=data type,Dc=constructor
 -- The data types were chosen to match the type variables in the type classes
            data PeopleD = PeopleDc [Char] deriving (Show,Eq)
            data BoatD a  = BoatDc a deriving (Show,Eq)
            data HouseBoatD a  = HouseBoatDc a  deriving (Show,Eq)
            data BoatHouseD a  = BoatHouseDc a deriving (Show,Eq)
            
             
            class ContainersC a b where -- suffix C= class
             insert :: b -&gt; a b -&gt; a b
             remove :: b -&gt; a b -&gt; a b
             whatsIn :: (a b) -&gt; [b]
            
            class SurfacesC a b where  
             put ::  b -&gt; a b -&gt; a b
             takeOff :: b -&gt; a b -&gt; a b
             whatsOn :: (a b) -&gt; [b] 
                           
            
            class PeopleC p
            class ContainersC h o =&gt; HousesC h o
            class (SurfacesC v o) =&gt; BoatsC v o
            class (HousesC h (v p), BoatsC v p) =&gt; BoatHousesC h v p
            class (BoatsC v p, HousesC v p, PeopleC p) =&gt; HouseBoatsC v p 
                         
           
            instance ContainersC BoatD PeopleD where
               whatsIn (BoatDc (PeopleDc x)) = [PeopleDc x]
            
            instance ContainersC BoatHouseD (BoatD PeopleD) where
                whatsIn (BoatHouseDc (BoatDc (PeopleDc x))) = [(BoatDc(PeopleDc x))]
          
            instance SurfacesC BoatD PeopleD where
               whatsOn (BoatDc (PeopleDc x)) = [PeopleDc x]
     
             test =  (head (whatsOn(head (whatsIn (BoatHouseDc (BoatDc (PeopleDc &quot;joe&quot;))))))) == 
                  (head (whatsOn(BoatDc (PeopleDc &quot;joe&quot;))))