generated at
FreeモナドでDSLを作って、後から実装を変える例

hs
-- DSLのInterfaceを定義 data CalcF a = Add Int a | Sub Int a | Mul Int a | Div Int a deriving (Functor) -- Freeモナドを作成 type Calc a = Free CalcF a -- ヘルパー関数の用意 add, sub, mul, div' :: Int -> Calc () add x = liftF (Add x ()) sub x = liftF (Sub x ()) mul x = liftF (Mul x ()) div' x = liftF (Div x ()) -- DSLを使ってコードを書く program :: Calc () program = do add 10 sub 5 mul 2 div' 2

hs
-- 実装1: 四則演算の結果をIntで返す interpret :: Calc a -> Int -> Int interpret (Free (Add x next)) state = interpret next (state + x) interpret (Free (Sub x next)) state = interpret next (state - x) interpret (Free (Mul x next)) state = interpret next (state * x) interpret (Free (Div x next)) state = interpret next (state `div` x) interpret (Pure _) state = state

hs
-- 実装2: 四則演算の結果をStringで返す interpretString :: Calc a -> Int -> String interpretString (Free (Add x next)) state = interpretString next (state + x) interpretString (Free (Sub x next)) state = interpretString next (state - x) interpretString (Free (Mul x next)) state = interpretString next (state * x) interpretString (Free (Div x next)) state = interpretString next (state `div` x) interpretString (Pure _) state = show state


ヘルパー関数は、ヘルパー関数に過ぎず、本質は型を組み合わせて構造を作るとこ
あとは、その構造をどういう風に解釈するか