Evg
Evg

Reputation: 3080

k-dimension Ord's typeclass with haskell

I want to implement function which takes two objects, all I want to know about this objects that them can be thought as values with fields and I want compare coresponding fields. (no matter what the fields and their types)

So I want to implement polymorthic function c which takes two values of same polymorphic type each of this values has N fields and corresponding fields has same type, also all fields are instances of Ord. So I want compare corresponding fields and build a list of Bools

c :: KD o => o -> o -> [Bool]
c o1 o2 = (\n -> (kth o1 n) == (kth o2 n) ) <$> [1..dimensions o1]

class KD c where
  dimensions :: c -> Int
  kth :: (Ord ?) => c -> Int -> ?
  
-- for example pair can be used as object with 2 dimensions 
instance (Ord a, Ord b, Show a, Show b) => KD (a,b) where
    dimensions _ = 2
    kth (a,_) 1 = undefined -- "I want a here"
    kth (_,b) 2 = undefined -- "I want b here"

I am stucked with KD typeclass and instance implementation, how can I achive this in Haskell ?

ps. Also i'am thinking about mapping each object to a list of Ints and then deal with compare Ints, but I don't know can I achive such a mapping for any type such as String, List etc..

class KDI c where
  map_ :: c -> [Integer]

Upvotes: 0

Views: 84

Answers (1)

Evg
Evg

Reputation: 3080

I realized that I can move comparsion inside typeclass like this

class KD c where
  dimensions :: c -> Int
  cmp_kth :: c -> c -> Int -> Ordering

instance (Ord a, Ord b) => KD (a,b) where
    dimensions _ = 2
    cmp_kth (a,_) (a',_) 0 = compare a a'
    cmp_kth (_,b) (_,b') 1 = compare b b'
    cmp_kth _ _ n = error $ "to big index from kth " ++ show n

data Men = Men {name::String,age::Int,height::Int} deriving Show
instance KD Men where
  dimensions _ = 3
  cmp_kth (Men n _ _) (Men n' _ _) 0 = compare n n'
  cmp_kth (Men _ n _) (Men _ n' _) 1 = compare n n'
  cmp_kth (Men _ _ n) (Men _ _ n') 2 = compare n n'

--cmp_kth (Men "J" 1 2) (Men "J" 2 2) 2

c :: KD o => o -> o -> [Bool]
c o1 o2 = (\n -> (cmp_kth o1 o2 n) == EQ ) <$> [0..(dimensions o1)-1]

And now can compare any "field enumerated objects" in an abstract way:

*Main> c (1,2) (3,2)
[False,True]
*Main> c (Men "J" 1 2) (Men "J" 2 2)
[True,False,True]

Also this typeclass can be used to implement abstract k-d tree

Upvotes: 3

Related Questions