-- 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])