data Tree a = Tip a | Fork (Tree a) (Tree a)I have included one instance declaration for the Show class below. Note how the instance has a prerequisite Show instance for the type parameter 'a'.
instance Show a => Show (Tree a) where show (Tip a) = "(Tip "++ show a ++ ")" show (Fork x y) = "(Fork " ++ show x ++" "++ show y ++")"Copy and paste these definition into your solution file (or start with the template above) and add the declarations for the following standard instances. Hint, you will need prerequisites for these as well. You may NOT use any deriving clauses in your solutions.
class Convertible a b where into:: a -> b outof:: b -> aAn example of this that a pair of lists (of the same length) is convertible with a list of pairs. We express this with the following instance.
instance Convertible ([a],[b]) [(a,b)] where into (x,y) = zip x y outof xs = unzip xsWrite instance declarations that respect both the structure and the invariant for the following types. You may or may not need prerequisites instances.
Convertible Bool (Maybe ())
Convertible (a -> b -> c) ((a,b) -> c)
Convertible [a] (Int -> a) -- you may assume that the list is infinite, and the Int is >= 0
data TagExp = I Int | C Char | F (TagExp -> TagExp) | D String [TagExp]One may think of the constructors, I, C, F, and D as tags. The constructor tells what kind of data is stored inside. An example encoding is the embedding of a list of Int into a TagExp. This can be defined by the following function.
encodeL :: [Int] -> TagExp encodeL [] = D "[]" [] encodeL (x:xs) = D ":" [I x,encodeL xs]One can decode a list of integer using the following function.
decodeL:: TagExp -> [Int] decodeL (D "[]" []) = [] decodeL (D ":" [I x,xs]) = x : decodeL xs decodeL other = error "Not a Tagged list"First note that the decodeL is a partial function. There are plenty of TagExp that don't encode lists. These examples suggest a rich mechanism for creating Convertible instances. Write the following instances.
Convertible Int TagExp
Convertibale Char TagExp
Convertible a TagExp => Convertible [a] TagExp
Convertible a TagExp => Convertible (Tree a) TagExp -- this is the Tree from question 1
(Convertible a TagExp,Convertible b TagExp) => Convertible (a->b) TagExp
(Convertible a TagExp,Convertible b TagExp) => Convertible (a,b) TagExp
class Convertible a TagExp => Generic a where toString:: a -> String equal:: a -> a -> Bool flatten:: a -> [Int] unflatten:: [Int] -> (a,[Int])The basic idea is that we call any type that is Convertible to a TagExp, a Genric type. Generic types support a wide variety operations. Here is a partial instance for pairs
instance (Generic a,Generic b) => Generic (a,b) where flatten (a,b) = flatten a ++ flatten b unflatten xs = ((x,y), zs) where (x,ys) = unflatten xs (y,zs) = unflatten yswrite the following instances for Generic. You may have to add some Convertible instances to complete the Genric instances.