OrenIshShalom
OrenIshShalom

Reputation: 7172

haskell ADT choosing the right type

Choosing the right type of MyTreeInt is OK with toString1 in the following code:

-- ***************
-- * MODULE Main *
-- ***************
module Main( main ) where

-- **********
-- * MyTree *
-- **********
data MyTree
   = MyTreeInt
   | MyTreeString

-- *************
-- * MyTreeInt *
-- *************
data MyTreeInt
   = MyTreeIntAtom  Int   
   | MyTreeIntPlus  MyTreeInt MyTreeInt
   | MyTreeIntMinus MyTreeInt MyTreeInt

-- ****************
-- * MyTreeString *
-- ****************
data MyTreeString
   = MyTreeStringAtom   String
   | MyTreeStringConcat String String

-- *************
-- * toString1 *
-- *************
toString1 :: MyTreeInt -> String
toString1 (MyTreeIntAtom     i) = "PPPPP"
toString1 (MyTreeIntPlus t1 t2) = "QQQQQ"

-- *************
-- * toString2 *
-- *************
-- toString2 :: MyTree -> String
-- toString2 (MyTreeIntAtom     i) = "RRRRR"
-- toString2 (MyTreeIntPlus t1 t2) = "SSSSS"

-- ********
-- * main *
-- ********
main :: IO ()
main = do putStrLn (toString1 (MyTreeIntAtom 8))

However, when the type hierarchy is greater than 1, like MyTree, is it possible to write toString2 to handle all int and string trees? Thanks in advance

Upvotes: 1

Views: 55

Answers (1)

chi
chi

Reputation: 116174

This type

data MyTree
   = MyTreeInt
   | MyTreeString

is completely unrelated to types MyTreeInt and MyTreeString. Above, these names are used as data constructor names, not as type names, so they do not refer to the other tree types. You might instead want something like

data MyTree
   = MyTreeInt MyTreeInt
   | MyTreeString MyTreeString

where, after the constructor name, we also include the type of the tree.

Then, we can write

toString2 :: MyTree -> String
toString2 (MyTreeInt    (MyTreeIntAtom      i))     = "A"
toString2 (MyTreeInt    (MyTreeIntPlus      t1 t2)) = "B"
toString2 (MyTreeString (MyTreeStringAtom   i))     = "C"
toString2 (MyTreeString (MyTreeStringConcat t1 t2)) = "D"

We can also reuse auxiliary functions, e.g.

toString2 :: MyTree -> String
toString2 (MyTreeInt    t) = treeIntToString t     -- this is toString1
toString2 (MyTreeString t) = treeStringToString t  -- this has to be defined

Upvotes: 3

Related Questions