Haskellとデザパタ練習その2(Adapterパターン)

phpで書かれたAdapterパターンのもHaskellで書いてみた。
http://www.doyouphp.jp/phpdp/phpdp_02-1-3_adapter.shtml
ここのやつ。

-- | これがもともとあって実績のあるモジュールだとする。(ShowFile.class.phpに対応するモジュール)
module File (showPlain, showHighlight) where

escapeHtml :: String -> String
escapeHtml = id                 -- 仮実装
highlight :: String -> IO ()
highlight = putStr              -- 仮実装

showPlain :: FilePath -> IO ()
showPlain filePath = do
  contents <- readFile filePath
  putStr $ "<pre>" ++ escapeHtml contents ++ "</pre>"

showHighlight :: FilePath -> IO ()
showHighlight filePath = readFile filePath >>= highlight
-- | 新しいインターフェース(DisplaySourceFile.class.phpに対応するモジュール)
module DisplaySourceFileClass (Display, display) where

class Display a where
  display :: a -> IO ()
-- | インターフェースの実装(DisplaySourceFileImpl.class.php対応するモジュール)
module DisplaySourceFileImpl (DisplaySource(DisplaySource), display ) where

import DisplaySourceFileClass
import File

data DisplaySource = DisplaySource FilePath deriving Show
instance Display DisplaySource where
  display (DisplaySource file) = showHighlight file
-- | クライアント(adapter_client.phpに対応するmain)
import DisplaySourceFileImpl

main :: IO ()
main = display (DisplaySource "File.lhs")

既存のFileモジュールには変更が加わっていないので利用実績をそこなっていない。
またmainからはFileモジュールが見えないようになっていて柔軟性が保たれている。

Template Methodのとき*1と同じようにインターフェースをclassで作った。
phpのほうではインターフェースの実装のところで継承と移譲の2パターンあったけど、Haskellのほうでは違いがでないような感じがした。

*1:http://d.hatena.ne.jp/suzuki-shin/20121010#1349875825