Finsk rabarberpaj

På begäran presenterar jag här en enkel finsk smuldegspaj. För den som inte är flytande i Haskell, gör så här:

  • Kopiera koden nedan och spara den i en fil som heter ‘torttu.hs’
  • Installera Haskell platform: http://hackage.haskell.org/platform/
  • Kör $ runhaskell torttu.hs
  • Alternativt: Se slutet av denna post.

God sommar önskar,

Jonas

-- | How to bake a Finnish Haskell pie (more or less)
--
-- Units are in grams (more or less)
--
-- God sommar! Jonas.
--
import qualified System.Environment as Env
import Data.Char 
import Data.List 
import Text.Printf

-- | List of ingredients
data Pie = Pie {
    fruit :: String,
    fruitWeight :: Float,
    wheatFlour :: Float,
    oats :: Float,
    sugar :: Float,
    butter :: Float
} 

-- | Pretty print ingredients
instance Show Pie where
    show (Pie f fw w o s b) = 
        concat . map pprint $ [
            (fw, (\(x:xs) -> toUpper x:xs) name), 
            (w, "Wheat flour\n"),
            (o, "Oats\n"),
            (s, "Sugar\n"),
            (b, "Butter") ] where
                name = (f ++ "\n")
                pprint :: (Float, String) -> String
                pprint (x, y) = printf "%f\tg\t %s" x y

data Fruit = Fruit { 
    name :: String, 
    peel :: Bool, 
    macerate :: Bool,
    plural :: String
    } 

instance Eq Fruit where
    (==) a b = name a == name b

instance Show Fruit where
    show = name

-- | Let's bake some pie!
main = do
    argv <- Env.getArgs
    let args = if length argv == 0 then ["rhubarb"] else argv
        fruit = getFruit $ head args in
        putStrLn $ hazPie fruit ++ show (getPieIngredients fruit) 
            ++ "\n\n" ++ concat (zipWith 
            (\x y -> show x ++ ". " ++ y ++ "\n")  [1..] (
                filter (/= "") [
                heatOven 200, 
                peelFruit fruit, 
                macerateFruit fruit,
                makeCrumble,
                makePie fruit,
                bakePie 200,
                servePie
                ])
            )

-- | Ceck default args
checkArgs x = if (length x) == 0 then "rhubarb" else head x

-- | Good fruits for a pie
fruits = [
    Fruit "rhubarb" True True "",  
    Fruit "apple" True True "s", 
    Fruit "prune" False True "s", 
    Fruit "banana" True False "s"
    ] 

getFruit name = 
    case juicy `elemIndex` fruits of
        Nothing -> error $ name ++ "? Yuck! No way!"
        Just a -> fruits !! a
    where juicy = Fruit (map toLower name) False False ""

getPieIngredients :: Fruit -> Pie
getPieIngredients x =  
    Pie { 
        fruit = name x, 
        fruitWeight = 300, 
        wheatFlour = 100, 
        oats = 50, 
        sugar = 100, 
        butter = 100 
    }

heatOven t = "Heat oven to " ++ show t ++ " C."

peelFruit fruit = if peel fruit 
    then "Peel the " ++ name fruit ++ plural fruit ++ "."
    else ""

macerateFruit fruit = if macerate fruit 
    then "Macerate " ++ name fruit ++ " with some extra sugar."
    else ""

makeCrumble = "Melt butter and mix with dry ingredients " ++ 
    "to make a crumble."

makePie fruit = "Drain and place the " ++ name fruit 
    ++ " in a baking pan and cover with crumble."

bakePie t = "Bake pie at " ++ show t ++ " C until golden brown, "
    ++ "approximately 20 min."

servePie = "Serve with whipped cream or creme fraiche." 

hazPie fruit = 
    let txt = "How I can haz Finnish " ++ name fruit ++ " pie!" 
        n = length txt in
            "\n" ++ txt ++ "\n" ++ take n (repeat '=') ++ "\n\n"

How I can haz Finnish rhubarb pie!
==================================

300.0	g	 Rhubarb
100.0	g	 Wheat flour
50.0	g	 Oats
100.0	g	 Sugar
100.0	g	 Butter

1. Heat oven to 200 C.
2. Peel the rhubarb.
3. Macerate the rhubarb with some extra sugar.
4. Melt butter and mix with dry ingredients to make a crumble.
5. Drain and place the rhubarb in a baking pan and cover with crumble.
6. Bake pie at 200 C until golden brown, approximately 20 min.
7. Serve with whipped cream or creme fraiche.

Leave a Reply

Your email address will not be published. Required fields are marked *