module a2 import StdEnv import StdMaybe class serialize a where write :: a [String] -> [String] read :: [String] -> Maybe (a, [String]) :: UNIT = UNIT :: EITHER a b = LEFT a | RIGHT b :: PAIR a b = PAIR a b :: CONS a = CONS String a :: ListG a :== EITHER (CONS UNIT) (CONS (PAIR a [a])) fromList :: [a] -> ListG a fromList [] = LEFT (CONS "Nil" UNIT) fromList [x:xs] = RIGHT (CONS "Cons" (PAIR x xs)) toList :: (ListG a) -> [a] toList (LEFT (CONS "Nil" UNIT)) = [] toList (RIGHT (CONS "Cons" (PAIR x xs))) = [x:xs] :: BinG a :== EITHER (CONS UNIT) (CONS (PAIR (Bin a) (PAIR a (Bin a)))) :: Bin a = Leaf | Bin (Bin a) a (Bin a) fromBin :: (Bin a) -> BinG a fromBin Leaf = LEFT (CONS "Leaf" UNIT) fromBin (Bin l a b) = RIGHT (CONS "Bin" (PAIR l (PAIR a b))) toBin :: (BinG a) -> Bin a toBin (LEFT (CONS "Leaf" UNIT)) = Leaf toBin (RIGHT (CONS "Bin" (PAIR l (PAIR a b)))) = Bin l a b instance serialize Int where write i c = [toString i:c] read [i:c] = Just (toInt i, c) read _ = Nothing instance serialize [a] | serialize a where write a c = write (fromList a) c read c = case read c of Just (l, c) = Just (toList l, c) Nothing = Nothing instance serialize UNIT where write UNIT c = ["UNIT":c] read ["UNIT":c] = Just (UNIT, c) read _ = Nothing instance serialize (EITHER a b) | serialize a & serialize b where write (LEFT a) c = ["LEFT":write a c] write (RIGHT a) c = ["RIGHT":write a c] read ["LEFT":c] = case read c of Just (a, c) = Just (LEFT a, c) Nothing = Nothing read ["RIGHT":c] = case read c of Just (a, c) = Just (RIGHT a, c) Nothing = Nothing read _ = Nothing instance serialize (PAIR a b) | serialize a & serialize b where write (PAIR a b) c = ["PAIR":write a (write b c)] read ["PAIR":c] = case read c of Just (a, c) = case read c of Just (b, c) = Just (PAIR a b, c) Nothing = Nothing Nothing = Nothing read _ = Nothing instance serialize (CONS a) | serialize a where write (CONS n a) c = ["CONS",n:write a c] read ["CONS",n:c] = case read c of Just (a, c) = Just (CONS n a, c) Nothing = Nothing read _ = Nothing Start :: Maybe ([Int], [String]) Start = read (write (fromList [1,2]) [])