Links und Funktionen
Sprachumschaltung

Navigationspfad
Sie sind hier: Startseite / Lehre / WS 2015/16 / Fortgeschrittene Funktionale Programmierung / Material / Applikative Arithmetische Ausdrücke


Inhaltsbereich

Applikative Arithmetische Ausdrücke

Beispiel für ((->) a) als applikativer Funktor: Auswerten arithmetischer Ausdrücke mit Variablen im Kontext einer Variablenbelegung

Haskell source code icon Eval.hs — Haskell source code, 2 KB (2201 bytes)

Dateiinhalt

-----------------------------------------------
-- Fortgeschrittene Funktionale Programmierung
-- Wintersemester 2015/16
-- LMU München
-- Steffen Jost
--
-- Generisches Code Beispiel für Funktionen als
-- als Applikative Funktoren.
-- 
-- Funktion eval' wird _implizit_ im Kontext 
-- einer Variablenbelegung ausgeführt.
--
-- Durch Applicative ist klar, dass die 
-- gegebene Variablenbelegung dabei nur 
-- gelesen, aber nicht verändert werden kann.
--

import Data.Maybe
import Data.Functor
import Control.Applicative

data Exp v = Var v
           | Val Int
           | Neg (Exp v)
           | Add (Exp v ) (Exp v )
           | Mul (Exp v ) (Exp v )
  deriving (Eq)

-- Terme hübsch anzeigen:
instance (Show a) => Show (Exp a) where
  showsPrec _ (Var v)   = shows v
  showsPrec _ (Val x)   = shows x
  showsPrec n (Neg p)   = showString "-" . showsPrec 2 p
  showsPrec n (Add p q) = showParen (n>1) $ (showsPrec 1 p) . showString " + " . showsPrec 1 q
  showsPrec n (Mul p q) = showParen (n>0) $ (showsPrec 2 p) . showString " * " . showsPrec 2 q

type Var = String
newtype Env = Env [(Var,Int)]  
  deriving Show

fetch :: Var -> Env -> Int
fetch v (Env env) = fromJust $ lookup v env

env1 = Env [("x",1),("y",2),("z",3)]
env2 = Env [("x",1),("y",1),("z",1)]
env3 = Env [("x",0),("y",10),("z",25)]

expX = Var "x"
expY = Var "y"
expZ = Var "z"

exp1 = Add expX expY
exp2 = Add expX $ Neg expY
exp3 = Mul (Add expX $ Neg expY) (Add expX expZ)
exp4 = Add (Val 1) (Mul (Neg exp3) exp2)


-- Ohne Funktor:
eval :: Exp String -> Env -> Int
eval (Var x )  env = fetch x env
eval (Val i )  env = i
eval (Neg p )  env = negate $ eval p env 
-- eval (Neg p )  env = negate $ eval p (Env [("x",0)]) -- bösartige Variante manipuliert Belegung!
eval (Add p q) env = eval p env + eval q env
eval (Mul p q) env = eval p env * eval q env

-- Mit Applikativem Funktor ((->) r):
eval' :: Exp String -> Env -> Int
eval' (Var x)   = fetch x
eval' (Val i)   = pure i        
eval' (Neg p)   = negate <$> eval' p
-- bösartige Variante in diesem Stil nicht realisierbar, wenn nur Applicative bekannt
eval' (Add p q) = pure (+) <*> eval' p <*> eval' q
eval' (Mul p q) =      (*) <$> eval' p <*> eval' q 


Artikelaktionen


Funktionsleiste