Haskell pattern match on tuple length in instances -


i want create data type can take tuple, of either length 2 or 3, , should contain types deriving num , ord. then, want pattern match on length of tuple in type class instances can decide function use based on tuple length. take @ non-compilable, pseudo-code below. there @ least 2 problems:

  1. dominates not derivable class

  2. i don't know how tuple, e.g. call fitnesses, variable out of data type when pattern matching in instance.

code:

data fits = i2 (int, int) | f2 (float, float) | i3 (int, int, int) | f3 (float, float, float)  data ind = ind { fitnesses :: fits                , otherinfo :: string                } deriving (dominates)  class dominates   dominates :: -> -> bool  instance dominates ind   dominates x@(_,_) y@(_,_) = x `dominates2` y -- takes 2 tuples of length 2   dominates x@(_,_,_) y@(_,_,_) = x `dominates3` y -- takes 2 tuples of length 3 

update:

data ind = ind { fitnesses :: fits                , otherinfo :: string                }  instance eq ind   (ind{ fitnesses = i2 x@(a1,a2) }) == (ind{ fitnesses = i2 y@(b1,b2) }) = indcmp2 x y == eq instance ord ind   (ind{ fitnesses = i2 x@(a1,a2) }) `compare` (ind{ fitnesses = i2 y@(b1,b2) }) = indcmp2 x y  indcmp2 :: (num a, ord a) => (a, a) -> (a, a) -> ordering indcmp2 x y   | a0 < b0 = lt   | a0 > b0 = gt   -- can assume (fst x) == (fst y) beneath   | a1 < b1 = lt   | a1 > b1 = gt   | a1 == b1 = eq       a0 = fst x     a1 = snd x     b0 = fst y     b1 = snd y 

this compiles. why necessary make instance of eq, if want ord? without eq-instance compiler complains "no instance (eq ind)".

you can provide instances 2- , 3-tuples.

class dominates   dominates :: -> -> bool  instance (num a, num b) => dominates (a,b)   dominates = dominates2 -- takes 2 tuples of length 2  instance (num a, num b, num c) => dominates (a,b,c)   dominates = dominates3 -- takes 2 tuples of length 3 

i wonder, however, if need.

you instead need pattern match on possible cases follows. no classes needed here.

dominates :: ind -> ind -> bool dominates (ind{ fitnesses = i2 (a1,a2) })           (ind{ fitnesses = i2 (b1,b2) }) = ... dominates (ind{ fitnesses = f2 (a1,a2) })           (ind{ fitnesses = f2 (b1,b2) }) = ... dominates (ind{ fitnesses = i3 (a1,a2,a3) })           (ind{ fitnesses = i3 (b1,b2,b3) }) = ... dominates (ind{ fitnesses = f3 (a1,a2,a3) })           (ind{ fitnesses = f3 (b1,b2,b3) }) = ... dominates _ _ = error "incompatible ind values!" 

example:

data ind = ind { fitnesses :: fits                , otherinfo :: string                }  -- no deriving ord here, want define manually  instance ord ind   (ind{ fitnesses = i2 x }) `compare` (ind{ fitnesses = i2 y }) = indcmp2 x y   -- other cases here 

Comments

Popular posts from this blog

javascript - Laravel datatable invalid JSON response -

java - Exception in thread "main" org.springframework.context.ApplicationContextException: Unable to start embedded container; -

sql server 2008 - My Sql Code Get An Error Of Msg 245, Level 16, State 1, Line 1 Conversion failed when converting the varchar value '8:45 AM' to data type int -