Reputation: 3080
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
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