----------------------------------------------------------------------------- -- Lambda Nu: January 25, 1993 -- -- The definitions in this file provide support for a simple implementation -- of Lambda Nu -- a generalisation of Lambda Var as described by Odersky, -- Rabin and Hudak in their POPL paper, January 1993. -- -- Of course, the implementation of the fuction `begin' is not sound. You must -- ensure that you use this function correctly -- the responsibility is on you, -- the programmer. -- -- Incidentally, the definitions in this file can only be used if the -- version of Gofer that you are using has been compiled with the correct -- set of primitives included. In addition, there is no support for these -- primitives in gofc, the Gofer compiler. -- -- Operator precedence table: ----------------------------------------------- infixr 3 =: infixr 2 >>, >>=, ? -- Lambda nu hacking: ------------------------------------------------------- primitive return "primLnReturn" :: a -> Cmd b a primitive (>>=) "primLnBind" :: Cmd a b -> (b -> Cmd a c) -> Cmd a c primitive primLnTagEq "primLnTagEq" :: Tag a -> Tag a -> Bool primitive newvar "primLnNew" :: Cmd a (Tag b) primitive assign "primLnAssign" :: Tag a -> a -> Cmd b () primitive (?) "primLnRead" :: Tag a -> (a -> Cmd b c) -> Cmd b c primitive io "primLnIo" :: ((a -> b) -> b) -> Cmd b a primitive begin "primLnBegin" :: Cmd a b -> a instance Eq (Tag a) where (==) = primLnTagEq (>>) :: Cmd c a -> Cmd c b -> Cmd c b f >> g = f >>= const g seq :: [Cmd m a] -> Cmd m () seq = foldr (>>) (return ()) new :: (Tag a -> Cmd b c) -> Cmd b c new = (>>=) newvar (=:) :: a -> Tag a -> Cmd b () value =: tag = assign tag value out :: (a -> a) -> Cmd a () out a = io (\c -> a (c ())) outConst = out . const pure :: Cmd a a -> a pure a = begin (a >>= outConst) deref :: Tag a -> Cmd b a deref t = t ? return -- Very simple monadic I/O in the Glasgow style: ----------------------------- primitive getch "primLnGetch" :: Cmd a Char primitive putchar "primLnPutchar" :: Char -> Cmd a () primitive system "primLnSystem" :: String -> Cmd a Int getchar :: Cmd a Char getchar = getch >>= \c -> putchar c >> return c puts :: String -> Cmd a () puts = seq . map putchar -- an abuse of pure to implement hbc's debugging hack: trace s a = pure (puts s >> return a) -- End of lambdaNu -----------------------------------------------------------