Avoid long tuple definitions in haskell -


for work hxt implemented following function:

-- | construction of 8 argument arrow 8-ary function. same -- implementation in @control.arrow.arrowlist.arr4@. arr8 :: arrowlist => (b1 -> b2 -> b3 -> b4 -> b5 -> b6 -> b7 -> b8 -> c)                 -> (b1, (b2, (b3, (b4, (b5, (b6, (b7, b8))))))) c arr8 f = arr ( \ ~(x1, ~(x2, ~(x3, ~(x4, ~(x5, ~(x6, ~(x7, x8)))))))                -> f x1 x2 x3 x4 x5 x6 x7 x8 ) 

as mentioned in haddock comment above function arr8 takes 8-ary function , returns 8 argument arrow. use function this: (x1 &&& x2 &&& ... x8) >>> arr8 f whereby x1 x8 arrows.

my question: there way avoid big tuple definition? there more elegant implementation of arr8?

info: used same code schema in function arr4 (see source code of arr4)

this works, though depends on quite deep , fragile typeclass magic. requires change tuple structure bit more regular. in particular, should type-level linked list preferring (a, (b, (c, ()))) (a, (b, c)).

{-# language typefamilies #-}  import control.arrow  -- need able refer functions presented tuples, generically. -- not possible in straightforward method, introduce type -- family recursively computes desired function type. in particular, -- can see -- --     fun (a, (b, ())) r ~ -> b -> r  type family   fun h      r :: * type instance fun ()     r =  r type instance fun (a, h) r =  -> fun h r  -- then, given our newfound function specification syntax we're in -- proper form give recursive typeclass definition of we're -- after.  class zup tup    zup :: fun tup r -> tup -> r  instance zup ()    zup r () = r  -- note recursive instance simple enough not require  -- undecidableinstances, techniques do. isn't -- terrible thing, if ui used it's author of typeclass -- , instances ensure typechecking terminates.  instance zup b => zup (a, b)    zup f ~(a, b) = zup (f a) b  arrtup :: (arrow a, zup b) => fun b c -> b c arrtup = arr . zup 

and can do

> zup (+) (1, (2, ())) 3  > :t arrtup (+) arrtup (+)   :: (num a1, arrow a, zup b n, fun n b c ~ (a1 -> a1 -> a1)) =>      b c  > arrtup (+) (1, (2, ())) 3 

if want define specific variants, they're arrtup.

arr8    :: arrow arr    => (a -> b -> c -> d -> e -> f -> g -> h -> r)   -> arr (a, (b, (c, (d, (e, (f, (g, (h, ())))))))) r arr8 = arrtup 

it's worth noting if define lazy uncurry

uncurryl :: (a -> b -> c) -> (a, b) -> c uncurryl f ~(a, b) = f b 

then can write recursive branch of zup in way illustrative what's going on here

instance zup b => zup (a, b)    zup f = uncurryl (zup . f) 

Comments

Popular posts from this blog

android - Get AccessToken using signpost OAuth without opening a browser (Two legged Oauth) -

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: mockito -

google shop client API returns 400 bad request error while adding an item -