Haskellでデザパタのお勉強(Template Method)
http://www.doyouphp.jp/phpdp/phpdp_02-1-1_template_method.shtml
ここのPHPコードをそのままHaskellにするっていうんじゃなくて、このプログラムを(Haskell勉強中の)僕がHaskellで書くんだったらこうかなって感じです。
元のPHPコードは上記のリンク先を見てもらうとして、Haskellのコード
-- phpのほうのAbstractDisplayクラス対応 class Show a => Display a where header :: a -> String body :: a -> [String] footer :: a -> String display :: a -> IO () display a = do putStrLn $ header a mapM_ putStrLn $ body a putStrLn $ footer a -- phpのほうのListDisplayクラスに対応 data List_ = List_ [String] deriving (Show) instance Display List_ where header _ = "<dl>" body (List_ xs) = map toListHtml $ zip [1..] xs where toListHtml (n, x) = "<dt>Item " ++ show n ++ "</dt><dd>" ++ x ++ "</dd>" footer _ = "</dl>" -- phpのほうのTableDisplayクラスに対応 data Table_ = Table_ [String] deriving (Show) instance Display Table_ where header _ = "<table border=\"1\" cellpadding=\"2\" cellspacing=\"2\">" body (Table_ xs) = map toTableHtml $ zip [1..] xs where toTableHtml (n, x) = "<tr><th>" ++ show n ++ "</th><td>" ++ x ++ "</td></tr>" footer _ = "</table>" lis :: [String] lis = ["Design Pattern", "Gang of Four", "Template Method Sample1", "Template Method Sample2"] main :: IO () main = do display $ List_ lis putStrLn "<hr>" display $ Table_ lis
PHPの抽象クラス(AbstractDisplay)をHaskellでは型クラス(Display)にして、実際の実装をする型(List_とTable_)はその型クラスのインスタンスにした。
違う実装を追加したかったら型を定義してDisplayのインスタンスにすればいい。
これで元の要件満たしてるんじゃないかなと思うんだけどどうだろう?