module Control.Monad.LazyIO
( LazyIO
, liftLazyIO
, runLazyIO
) where
import System.IO.Unsafe (unsafeInterleaveIO)
newtype LazyIO a = LazyIO { forall a. LazyIO a -> IO a
unLazyIO :: IO a }
instance Functor LazyIO where
fmap :: forall a b. (a -> b) -> LazyIO a -> LazyIO b
fmap a -> b
f LazyIO a
io = IO b -> LazyIO b
forall a. IO a -> LazyIO a
LazyIO (IO b -> LazyIO b) -> IO b -> LazyIO b
forall a b. (a -> b) -> a -> b
$ (a -> b) -> IO a -> IO b
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f (IO a -> IO a
forall a. IO a -> IO a
unsafeInterleaveIO (IO a -> IO a) -> IO a -> IO a
forall a b. (a -> b) -> a -> b
$ LazyIO a -> IO a
forall a. LazyIO a -> IO a
unLazyIO LazyIO a
io)
instance Applicative LazyIO where
pure :: forall a. a -> LazyIO a
pure = IO a -> LazyIO a
forall a. IO a -> LazyIO a
LazyIO (IO a -> LazyIO a) -> (a -> IO a) -> a -> LazyIO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> IO a
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
LazyIO (a -> b)
f <*> :: forall a b. LazyIO (a -> b) -> LazyIO a -> LazyIO b
<*> LazyIO a
g = IO b -> LazyIO b
forall a. IO a -> LazyIO a
LazyIO (IO b -> LazyIO b) -> IO b -> LazyIO b
forall a b. (a -> b) -> a -> b
$ do
a -> b
f' <- IO (a -> b) -> IO (a -> b)
forall a. IO a -> IO a
unsafeInterleaveIO (IO (a -> b) -> IO (a -> b)) -> IO (a -> b) -> IO (a -> b)
forall a b. (a -> b) -> a -> b
$ LazyIO (a -> b) -> IO (a -> b)
forall a. LazyIO a -> IO a
unLazyIO LazyIO (a -> b)
f
a
g' <- IO a -> IO a
forall a. IO a -> IO a
unsafeInterleaveIO (IO a -> IO a) -> IO a -> IO a
forall a b. (a -> b) -> a -> b
$ LazyIO a -> IO a
forall a. LazyIO a -> IO a
unLazyIO LazyIO a
g
b -> IO b
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (b -> IO b) -> b -> IO b
forall a b. (a -> b) -> a -> b
$ a -> b
f' a
g'
liftLazyIO :: IO a -> LazyIO a
liftLazyIO :: forall a. IO a -> LazyIO a
liftLazyIO = IO a -> LazyIO a
forall a. IO a -> LazyIO a
LazyIO
runLazyIO :: LazyIO a -> IO a
runLazyIO :: forall a. LazyIO a -> IO a
runLazyIO = IO a -> IO a
forall a. IO a -> IO a
unsafeInterleaveIO (IO a -> IO a) -> (LazyIO a -> IO a) -> LazyIO a -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LazyIO a -> IO a
forall a. LazyIO a -> IO a
unLazyIO