Haskell ADT выбирает правильный тип - PullRequest
0 голосов
/ 28 апреля 2018

Выбор правильного типа MyTreeInt равен OK с toString1 в следующем коде:

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

Однако, когда иерархия типов больше 1, как MyTree , можно ли написать toString2 в обрабатывать все целые и строковые деревья? Заранее спасибо

1 Ответ

0 голосов
/ 28 апреля 2018

Этот тип

data MyTree
   = MyTreeInt
   | MyTreeString

совершенно не относится к типам MyTreeInt и MyTreeString. Выше эти имена используются как имена конструкторов данных, а не как имена типов, поэтому они не ссылаются на другие типы деревьев. Вместо этого вы можете захотеть что-то вроде

data MyTree
   = MyTreeInt MyTreeInt
   | MyTreeString MyTreeString

где после имени конструктора мы также включаем тип дерева.

Тогда мы можем написать

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"

Мы также можем повторно использовать вспомогательные функции, например,

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