http://isorecursive.livejournal.com/ ([identity profile] isorecursive.livejournal.com) wrote in [personal profile] stdray 2012-10-17 06:25 am (UTC)

{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, UnicodeSyntax, KindSignatures, LambdaCase #-}

import Prelude.Unicode

-- Ребята, нам нужно чтобы делался хлеб
{-
data Bread = Bread

bakeBread = Bread
-}

-- Нам нужно, чтобы хлеб не просто делался, а выпекался в печке
{-
data Oven (m ∷ * → *) = Oven

bakeBread ∷ Monad m ⇒ Oven m → m Bread
bakeBread oven = return Bread
-}

-- Нам нужно, чтобы печки были разных видов
{-
class Oven (o ∷ (* → *) → *) where
-}

-- Нам нужно, чтобы газовая печь не могла печь без газа
data GasOven m = GasOven { gasAvailable ∷ m Bool }

class Oven (o ∷ (* → *) → *) where
  canBake ∷ o m → m Bool

instance Oven GasOven where
  canBake = gasAvailable

-- Нам нужно, чтобы печки могли выпекать ещё и пирожки (отдельно - с мясом, отдельно - с капустой), и торты
data Bread   = Bread
data Cake    = Cake
data Patty f = Patty { filling ∷ f }

bake ∷ (Monad m, Oven oven) ⇒ oven m → (oven m → m bakery) → m bakery
bake oven wf = canBake oven >>= \case
  True  → wf oven
  False → error "Your oven is dead!"

bakeBread        oven = bake oven $ return ∘ const Bread
bakeCake         oven = bake oven $ return ∘ const Cake
bakeMeatPatty    oven = bake oven $ return ∘ const (Patty "Meat")
bakeCabbagePatty oven = bake oven $ return ∘ const (Patty "Cabbage")

-- Нам нужно, чтобы хлеб, пирожки, и торты выпекались по разным рецептам
class Recipe bakery ingredients where
  cook ∷ (Monad m, Oven oven) ⇒ oven m → ingredients → m bakery

data Meat    = Meat
data Cabbage = Cabbage
   
instance Recipe (Patty Meat) Meat where
  cook oven Meat = bake oven $ return ∘ const (Patty Meat)

instance Recipe (Patty Cabbage) Cabbage where
  cook oven Cabbage = bake oven $ return ∘ const (Patty Cabbage)

-- Нам нужно, чтобы в печи можно было обжигать кирпичи
data Brick = Brick

bakeBrick oven = bake oven $ return ∘ const Brick

Post a comment in response:

This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting