-- chameleon -d zip.ch -- For translation call chameleon -o zip.hs zip.ch interface Prelude mZip2 :: [a] -> [b] -> [(a,b)] mZip2 (x:xs) (y:ys) = (x,y) : (mZip2 xs ys) mzip2 _ _ = [] -- enforce -- class Zip ([a]->[b]->c) where zip :: [a]->[b]->c rule MZip x ==> x=[a]->[b]->c -- FD rule MZip (a->b->c), MZip (a->d->c) ==> b=d rule MZip (a->b->c), MZip (d->b->c) ==> a=d -- base case overload mZip :: [a]->[b]->[(a,b)] where mZip= mZip2 -- instance-improvement -- rule MZip ([a]->c->[(a,b)]) ==> c=[b] -- as specified by FD rule MZip ([a]->d->[c]) ==> d=[b],c=(a,b) -- though we employ a slightly stronger rule -- to achieve the desired typing rule MZip (c->[b]->[(a,b)]) ==> c=[a] -- general case overload mZip :: (MZip ([(a,b)]->[cs]->r)) => [a]->[b]->[cs]->r where mZip as bs cs = mZip (mZip2 as bs) cs -- instance improvements for this case is trivial -- NOTE: -- overload zip :: (Zip ([(a,b)]->cs->r)) => [a]->[b]->cs->r where -- is too general --instance (Zip ([(a,b)]->[cs]->r)) => Zip ([a]->[b]->[cs]->r) where -- zip as bs cs = zip (zip2 as bs) cs -- annoations are not necessary here --e1 :: [(Bool,Char)] e1 = head (mZip [True,False] ['a','b','c']) --e2 :: [((Bool,Char),Int)] e2 = head (mZip [True,False] ['a','b','c'] [1::Int,2])