1 {-# LANGUAGE FlexibleInstances #-}
2 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
3 {-# LANGUAGE MultiParamTypeClasses #-}
4 {-# LANGUAGE TypeFamilies #-}
5 module TFHOE.Repr.Host where
7 import Control.Monad.IO.Class (MonadIO(..))
10 import TFHOE.Lib.Control.Monad
15 -- | Host-circular interpreter,
16 -- producing a host-term of host-type @h@,
17 -- wrapped inside @fun@ because of 'Expr_Fun'
18 -- ability to control its callings ('inline', 'val', and 'lazy').
19 newtype Repr_Host fun h
21 { unRepr_Host :: fun h }
22 deriving (Applicative, Functor, Monad, MonadIO)
24 instance MonadIO fun => Expr_Fun fun (Repr_Host fun) where
25 type Fun_from_Repr (Repr_Host fun) = fun
26 app = liftM2Join $ \f a -> Repr_Host $ f $ return a
27 inline f = return $ unRepr_Host . f . Repr_Host
28 val f = return $ (>>= unRepr_Host . f . Repr_Host . return)
29 lazy f = return $ ((>>= unRepr_Host . f . Repr_Host) . expr_fun_lazy_share)
30 instance Monad repr => Expr_Bool (Repr_Host repr) where
32 neg = liftMJoin $ return . not
33 and = liftM2Join $ \x y -> return $ x && y
34 or = liftM2Join $ \x y -> return $ x || y
35 instance Monad repr => Expr_Int (Repr_Host repr) where
37 add = liftM2Join $ \x y -> return $ x + y
38 --instance Monad m => Expr_Eq (Host m) where
39 -- eq = liftM2Join $ \x y -> return $ x == y
41 host_repr :: Repr_Host repr h -> repr h
42 host_repr = unRepr_Host
44 -- | Utility for storing arguments of 'lazy' into an 'IORef'.
45 expr_fun_lazy_share :: MonadIO m => m a -> m (m a)
46 expr_fun_lazy_share m = do
47 r <- liftIO $ newIORef (False, m)
49 (already_evaluated, m') <- liftIO $ readIORef r
54 liftIO $ writeIORef r (True, return v)