Advanced Functional Programming Tim Sheard 1 Lecture 6 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture.

Slides:



Advertisements
Similar presentations
Functional Programming Lecture 10 - type checking.
Advertisements

Modern Programming Languages, 2nd ed.
Type Checking, Inference, & Elaboration CS153: Compilers Greg Morrisett.
Kathleen Fisher cs242 Reading: “A history of Haskell: Being lazy with class”,A history of Haskell: Being lazy with class Section 6.4 and Section 7 “Monads.
Tim Sheard Oregon Graduate Institute Lecture 8: Operational Semantics of MetaML CSE 510 Section FSC Winter 2005 Winter 2005.
ML Exceptions.1 Standard ML Exceptions. ML Exceptions.2 Exceptions – The Need  An extensive part of the code is error handling  A function F can return.
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Dan Grossman Winter 2013.
ML: a quasi-functional language with strong typing Conventional syntax: - val x = 5; (*user input *) val x = 5: int (*system response*) - fun len lis =
Tim Sheard Oregon Graduate Institute Lecture 4: Staging Interpreters CSE 510 Section FSC Winter 2004 Winter 2004.
Grab Bag of Interesting Stuff. Topics Higher kinded types Files and handles IOError Arrays.
Monads. A monad orders actions An action is any computation that has a natural notion of order. I.e. one thing happens before another. – IO is the action.
A Type System for MetaML MetaML types as an Omega program Lecture 12.
Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004.
Cse321, Programming Languages and Compilers 1 6/19/2015 Lecture #18, March 14, 2007 Syntax directed translations, Meanings of programs, Rules for writing.
Advanced Programming Handout 12 Higher-Order Types (SOE Chapter 18)
Introducing Monads Lecture 3, Designing and Using Combinators John Hughes.
Introduction to ML Last time: Basics: integers, Booleans, tuples,... simple functions introduction to data types This time, we continue writing an evaluator.
Cse536 Functional Programming 1 6/23/2015 Lecture #17, Dec. 1, 2004 Todays Topics – Higher Order types »Type constructors that take types as arguments.
Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004.
CS510AP Quick Check Monads. QuickCheck Quick check is a Haskell library for doing random testing. You can read more about quickcheck at –
Tim Sheard Oregon Graduate Institute Lecture 6: Monadic Staging of the RE language CSE 510 Section FSC Winter 2004 Winter 2004.
Staging in Haskell What is Staging What does it Mean Using Template Haskell.
Deriving Combinator Implementations Lecture 4, Designing and Using Combinators John Hughes.
Advanced Functional Programming 2009 Ulf Norell (lecture by Jean-Philippe Bernardy)
Functional Programming guest lecture by Tim Sheard Parsing in Haskell Defining Parsing Combinators.
Advanced Functional Programming Tim Sheard 1 Lecture 14 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture.
Advanced Programming Andrew Black and Tim Sheard Lecture 11 Parsing Combinators.
Advanced Functional Programming Tim Sheard 1 Lecture 6 Functional Programming Tim Sheard & Mark Jones Monads & Interpreters.
A Second Look At ML 1. Outline Patterns Local variable definitions A sorting example 2.
© M. Winter COSC 4P41 – Functional Programming Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.
A Third Look At ML Chapter NineModern Programming Languages, 2nd ed.1.
Advanced Functional Programming Tim Sheard 1 Lecture 18 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture.
Parsec Parsing. Parsec Parsec one of the standard libraries for building libraries. It is a combinator parser A parser parses a sequence of elements to.
Arvind Computer Science and Artificial Intelligence Laboratory M.I.T. L13-1 October 26, 2006http:// Monadic Programming October.
Functional Programming Lecture 5 - Tuples. Packaging several values together Sometimes you need to package up several values into a single object –A function.
A Staged Semantics of Overloading (preliminary) Bill Harrison & Tim Sheard.
Error Example - 65/4; ! Toplevel input: ! 65/4; ! ^^ ! Type clash: expression of type ! int ! cannot have type ! real.
Grab Bag of Interesting Stuff. Higher Order types Type constructors are higher order since they take types as input and return types as output. Some type.
Chapter SevenModern Programming Languages1 A Second Look At ML.
Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:
FUNCTIONAL PROGRAMING AT WORK - HASKELL AND DOMAIN SPECIFIC LANGUAGES Dr. John Peterson Western State Colorado University.
Environments, Stores, and Interpreters. Overview As we study languages we will build small languages that illustrate language features We will use two.
Advanced Functional Programming Tim Sheard 1 Lecture 16 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:
Advanced Functional Programming 2010
Haskell Chapter 7.
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Dan Grossman Spring 2013.
Tim Sheard Oregon Graduate Institute
Advanced Functional Programming
PROGRAMMING IN HASKELL
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Zach Tatlock Winter 2018.
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Dan Grossman Spring 2017.
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Dan Grossman Autumn 2018.
Advanced Functional Programming
Advanced Functional Programming
Advanced Functional Programming
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Dan Grossman Autumn 2017.
3.4 Local Binding Recall Scheme's let: > (let ((x 5)‏ (y 6))
Advanced Functional Programming
Environments, Stores, and Interpreters
Functional Programming
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Dan Grossman Spring 2016.
Grab Bag of Interesting Stuff
Programming Languages
CSE 341 Lecture 11 b closures; scoping rules
PROGRAMMING IN HASKELL
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Dan Grossman Spring 2019.
Advanced Functional Programming
Presentation transcript:

Advanced Functional Programming Tim Sheard 1 Lecture 6 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture 7: Monad Transformers Monads as a data structure Transformers as functions Visualizing Transforms (using MetaML) Transformers as classes

Advanced Functional Programming Tim Sheard 2 Lecture 6 Monad Transformers A Monad is an ADT An ADT is a collection of related (typed) functions that interface some data. A Monad Transformer is a function from one monad ADT to another. In order to type a monad transformer we need 2 extensions to Haskell’s type system Higher order type constructors Rank2 (local) polymorphism

Advanced Functional Programming Tim Sheard 3 Lecture 6 Recall definition of monad data Mon m = Mon (forall a. a -> m a) (forall a b. m a -> (a -> m b) -> m b) Monad is a type constructor that takes another type constructor as an argument Mon : * -> * Each component of the pair which is the argument to Mon is a polymorphic function. (forall a. a -> m a)

Advanced Functional Programming Tim Sheard 4 Lecture 6 Transformers type Transformer s t = Mon s -> Mon t transform :: Mon S -> Mon T The type T probably mentions S

Advanced Functional Programming Tim Sheard 5 Lecture 6 Three monads --Id data Id x = Id x --Env data Env e x = Env (e -> x) --State data State s x = State (s -> (x,s))

Advanced Functional Programming Tim Sheard 6 Lecture 6 Id monad data Id x = Id x idMon :: Mon Id idMon = let bind x f = case x of {(Id y) -> f y } bind (Id y) f = f y in Mon Id bind runId :: Id a -> a runId (Id x) = x

Advanced Functional Programming Tim Sheard 7 Lecture 6 Env monad data Env e x = Env (e -> x) envMon :: Mon (Env e) envMon = let unit x = Env(\ _ -> x) bind (Env g) f = Env(\ e -> case f(g e) of Env h -> h e) in Mon unit bind readEnv = Env(\ e -> e) inEnv e (Env f) = Env(\ e2 -> f e)

Advanced Functional Programming Tim Sheard 8 Lecture 6 State Monad data State s x = State (s -> (x,s)) stateMon :: Mon (State s) stateMon = let unit x = State(\ s -> (x,s)) bind (State g) f = State(\ s -> let (a,s') = g s State h = f a in h s') in Mon unit bind readSt = State(\ s -> (s,s)) writeSt x = State(\ s -> ((),x))

Advanced Functional Programming Tim Sheard 9 Lecture 6 Env Transformer data WithEnv env m a = WithEnv (env -> m a) m is the old monad env is the type of the env being added to m Also need to lift old computations and the function rdEnv and inEnv data Fenv m = Fenv (forall a e. m a -> WithEnv e m a) (forall e. WithEnv e m e) (forall a e. e -> WithEnv e m a -> WithEnv e m a)

Advanced Functional Programming Tim Sheard 10 Lecture 6 The transformer transEnv :: Mon m -> (Mon (WithEnv e m),Fenv m) transEnv (Mon unitM bindM) = let unitEnv x = WithEnv(\ rho -> unitM x) bindEnv x f = WithEnv(\ rho -> let (WithEnv h) = x in bindM (h rho) (\ a -> let (WithEnv g) = f a in g rho)) lift2 x = WithEnv(\ rho -> x) rdEnv = WithEnv(\ rho -> unitM rho) inEnv rho (WithEnv x) = WithEnv(\ _ -> x rho) in (Mon unitEnv bindEnv,Fenv lift2 rdEnv inEnv)

Advanced Functional Programming Tim Sheard 11 Lecture 6 The State Transformer data WithStore s m a = WithStore (s -> m (a,s)) data Fstore m = Fstore (forall a s. m a -> WithStore s m a) (forall s. (s -> s) -> WithStore s m ()) (forall s. WithStore s m s)

Advanced Functional Programming Tim Sheard 12 Lecture 6 The transformer transStore :: Mon m -> (Mon (WithStore s m),Fstore m) transStore (Mon unitM bindM) = let unitStore x = WithStore(\sigma -> unitM(x,sigma)) bindStore x f = WithStore(\ sigma0 -> let (WithStore h) = x in bindM (h sigma0) (\ (a,sigma1) -> let (WithStore g) = f a in g sigma1 ) ) lift2 x = WithStore(\ sigma -> bindM x (\ y -> unitM(y,sigma))) update f = WithStore(\ sigma -> unitM((),f sigma)) get = WithStore(\sigma -> unitM(sigma,sigma)) in (Mon unitStore bindStore,Fstore lift2 update get)

Advanced Functional Programming Tim Sheard 13 Lecture 6 An example ex1 :: (Mon (WithStore a (WithEnv b Id)),Fenv Id,Fstore (WithEnv c Id)) ex1 = let (mon1,funs1) = transEnv idMon (mon2,funs2) = transStore mon1 in (mon2,funs1,funs2) The problem is that the functions on the inner monad are not lifted. We can use Haskell Classes to fix this.

Advanced Functional Programming Tim Sheard 14 Lecture 6 Making transformers “visible” in MetaML datatype ('M : * -> * ) Monad2 = Mon2 of (['a]. 'a 'M>) * (['a,'b]. ('a -> 'b 'M) -> 'b 'M>); val id2 = (Mon2 (, fn f => let val (Id y) = x in f y end>));

Advanced Functional Programming Tim Sheard 15 Lecture 6 Env transformer at the code level fun TransEnv2 (Mon2(unitM,bindM)) = let val unitEnv = Tenv(fn rho => ~unitM x)> in Mon2(unitEnv, fn f => Tenv(fn rho => let val (Tenv h) = x in ~(force (force bindM ) let val (Tenv g) = f a in g rho end> ) end)>) end;

Advanced Functional Programming Tim Sheard 16 Lecture 6 State transformer at code level fun TransStore2 (Mon2(unitM,bindM)) = Mon2 ( Tstore(fn sigma => ~unitM (x,sigma))>, fn f => Tstore(fn sigma0 => let val (Tstore h) = x in ~(force (force bindM ) let val (a,sigma1) = w val (Tstore g) = f a in g sigma1 end> ) end)>);

Advanced Functional Programming Tim Sheard 17 Lecture 6 An example -| fun bindof (Mon2(x,y)) = y; val bindof = Fn : ['a,'b,'c]. 'c Monad2 -> ('b -> 'a 'c ) -> 'a 'c > val ans = bindof(TransStore2 (TransEnv2 id2));

Advanced Functional Programming Tim Sheard 18 Lecture 6 -| val ans = (fn b => Tstore (fn c => let val Tstore d = a in Tenv (fn e => let val Tenv f = d c val Id g = f e val (i,h) = g val Tstore j = b i val Tenv k = j h in k e end) end)))> : ('3 -> ('4,'2,('1,Id) Tenv) Tstore) -> ('4,'2,('1,Id) Tenv) Tstore>

Advanced Functional Programming Tim Sheard 19 Lecture 6 Using Haskell Classes This part of the lecture is based upon the Monad library developed (in part) by Iavor Diatchki. Uses classes instead of data stuctures to encode monads. Instances then are used to encode monad transformers.

Advanced Functional Programming Tim Sheard 20 Lecture 6 From IxEnvMT.hs newtype WithEnv e m a = E { unE :: e -> m a } withEnv :: e -> WithEnv e m a -> m a withEnv e (E f) = f e mapEnv :: Monad m => (e2 -> e1) -> WithEnv e1 m a -> WithEnv e2 m a mapEnv f (E m) = E (\e -> m (f e))

Advanced Functional Programming Tim Sheard 21 Lecture 6 From IxEnvMT.hs cont. instance Monad m => Functor (WithEnv e m) where fmap = liftM instance Monad m => Monad (WithEnv e m) where return = lift. return E m >>= f = E (\e -> do { x <- m e ; unE (f x) e }) E m >> n = E (\e -> m e >> withEnv e n) fail = lift. fail

Advanced Functional Programming Tim Sheard 22 Lecture 6 IxStateMT.hs newtype WithState s m a = S { ($$) :: s -> m (a,s) } withSt :: Monad m => s -> WithState s m a -> m a withSt s = liftM fst. withStS s withStS :: s -> WithState s m a -> m (a,s) withStS s (S f) = f s mapState :: Monad m => (t -> s) -> (s -> t) -> WithState s m a -> WithState t m a mapState inF outF (S m) = S (liftM outF'. m. inF) where outF' (a,s) = (a, outF s)

Advanced Functional Programming Tim Sheard 23 Lecture 6 IxStateMT.hs continued instance Monad m => Functor (WithState s m) where fmap = liftM instance Monad m => Monad (WithState s m) where return x = S (\s -> return (x,s)) S m >>= f = S (\s -> m s >>= \(a,s') -> f a $$ s') fail msg = S (\s -> fail msg)

Advanced Functional Programming Tim Sheard 24 Lecture 6 To lift from one monad to another Add a new class for monad transformers class MT t where lift :: (Monad m, Monad (t m)) => m a -> t m a

Advanced Functional Programming Tim Sheard 25 Lecture 6 Add instance for each Transformer instance MT (WithState s) where lift m = S (\s -> do a <- m; return (a,s)) instance MT (WithEnv e) where lift = E. Const Each Transformer also supports a class of operations – the HasXX classes

Advanced Functional Programming Tim Sheard 26 Lecture 6 HasEnv class Monad m => HasEnv m ix e | m ix -> e where getEnv :: ix -> m e inEnv :: ix -> e -> m a -> m a inModEnv :: ix -> (e -> e) -> m a -> m a inEnv ix e = inModEnv ix (const e) inModEnv ix f m = do { e <- getEnv ix ; inEnv ix (f e) m } -- define at least one of: -- * getEnv, inEnv -- * getEnv, inModEnv

Advanced Functional Programming Tim Sheard 27 Lecture 6 HasState class Monad m => HasState m ix s | m ix -> s where updSt :: ix -> (s -> s) -> m s -- returns the old state updSt_ :: ix -> (s -> s) -> m () getSt :: ix -> m s setSt :: ix -> s -> m s -- returns the old state setSt_ :: ix -> s -> m () updSt ix f = do s <- getSt ix; setSt ix (f s) setSt ix = updSt ix. const getSt ix = updSt ix id updSt_ ix f = do updSt ix f; return () setSt_ ix s = do setSt ix s; return () -- define at least one of: -- * updSt -- * getSt, setSt

Advanced Functional Programming Tim Sheard 28 Lecture 6 Example use -- Interpreter Syntax type Name = String type Message = String data E = E :+: E | E :-: E | E :*: E | E :/: E | Int Int | Let Name E E | Var Name | Print Message E | ReadRef Name | WriteRef Name E | E :> E

Advanced Functional Programming Tim Sheard 29 Lecture 6 The eval function eval (e1 :+: e2) = liftM2 (+) (eval e1) (eval e2) eval (e1 :-: e2) = liftM2 (-) (eval e1) (eval e2) eval (e1 :*: e2) = liftM2 (*) (eval e1) (eval e2) eval (e1 :/: e2) = liftM2 div (eval e1) $ (do x <- eval e2 when (x == 0) (raise "division by 0") return x) eval (Int x) = return x eval (Let x e1 e2) = do v <- eval e1; inModEnv ((x,v):) (eval e2) eval (Var x) = (maybe (raise ("undefined variable: " ++ x)) return). (lookup x =<< getEnv) eval (Print x e) = do v <- eval e output (x ++ show v) return v eval (ReadRef x) = maybe (return 0) return. lookup x =<< getSt eval (WriteRef x e) = do v <- eval e updSt_ $ \s -> (x,v) : filter ((/= x). fst) s return 0 eval (e1 :> e2) = eval e1 >> eval e2

Advanced Functional Programming Tim Sheard 30 Lecture 6 The Type of Eval eval :: (HasState a Z [([Char],Int)], HasOutput a Z [Char], HasEnv a Z [([Char],Int)], HasExcept a [Char]) => E -> a Int

Advanced Functional Programming Tim Sheard 31 Lecture 6 What Monad has all these? type Heap = [(Name,Int)] type Env = [(Name,Int)] type M = WithState Heap ( WithEnv Env ( WithOutput String ( WithExcept String IO )))

Advanced Functional Programming Tim Sheard 32 Lecture 6 instance Monad m => HasEnv (WithEnv e m) Z e where getEnv _ = E return inModEnv _ = mapEnv instance HasEnv m ix e => HasEnv (WithEnv e' m) (S ix) e where getEnv (Next ix) = lift (getEnv ix) inModEnv (Next ix) f m = E (\e -> inModEnv ix f (withEnv e m)) instance HasState m ix s => HasState (WithEnv e m) ix s where updSt ix = lift. updSt ix instance HasOutput m ix o => HasOutput (WithEnv e m) ix o where outputTree ix = lift. outputTree ix

Advanced Functional Programming Tim Sheard 33 Lecture 6 Run for the monad Then run for the monad is the code that actually specifies how the pieces are put together! run :: M a -> IO a run m = do x <- removeExcept $ listOutput $ withEnv [] $ withSt [] m case x of Left err -> error ("error: " ++ err) Right (v,o) -> mapM putStrLn o >> return v

Advanced Functional Programming Tim Sheard 34 Lecture 6 Advanced Features Multiple occurences of Env, State, etc.