Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
This module defines an IO monad for linearly working with system resources like files. It provides tools to take resources that are currently unsafely accessible from System.IO and use them in this monad.
Import this module qualified to avoid name clashes.
To use this RIO monad, create some RIO
computation,
run it to get a System.IO computation.
A simple example
>>>
:set -XLinearTypes
>>>
:set -XQualifiedDo
>>>
:set -XNoImplicitPrelude
>>>
import qualified System.IO.Resource as Linear
>>>
import qualified Control.Functor.Linear as Control
>>>
import qualified Data.Text as Text
>>>
import Prelude.Linear
>>>
import qualified Prelude
>>>
:{
linearWriteToFile :: IO () linearWriteToFile = Linear.run Prelude.$ Control.do handle1 <- Linear.openFile "/home/user/test.txt" Linear.WriteMode handle2 <- Linear.hPutStrLn handle1 (Text.pack "hello there") () <- Linear.hClose handle2 Control.return (Ur ()) :}
To enable do notation, QualifiedDo
extension is used. But since QualifiedDo
only modifies the desugaring of binds, we still need to qualify return
.
Synopsis
- data RIO a
- run :: RIO (Ur a) -> IO a
- data Handle
- openFile :: FilePath -> IOMode -> RIO Handle
- data IOMode
- hClose :: Handle %1 -> RIO ()
- hIsEOF :: Handle %1 -> RIO (Ur Bool, Handle)
- hGetChar :: Handle %1 -> RIO (Ur Char, Handle)
- hPutChar :: Handle %1 -> Char -> RIO Handle
- hGetLine :: Handle %1 -> RIO (Ur Text, Handle)
- hPutStr :: Handle %1 -> Text -> RIO Handle
- hPutStrLn :: Handle %1 -> Text -> RIO Handle
- data UnsafeResource a
- unsafeRelease :: UnsafeResource a %1 -> RIO ()
- unsafeAcquire :: IO (Ur a) -> (a -> IO ()) -> RIO (UnsafeResource a)
- unsafeFromSystemIOResource :: (a -> IO b) -> UnsafeResource a %1 -> RIO (Ur b, UnsafeResource a)
- unsafeFromSystemIOResource_ :: (a -> IO ()) -> UnsafeResource a %1 -> RIO (UnsafeResource a)
The Resource I/O Monad
The resource-aware I/O monad. This monad guarantees that acquired resources are always released.
run :: RIO (Ur a) -> IO a Source #
Take a RIO
computation with a value a
that is not linearly bound and
make it a System.IO computation.
Using Resource Handles
File I/O
See openFile
Working with Handles
Creating new types of resources
data UnsafeResource a Source #
The type of system resources. To create and use resources, you need to use the API since the constructor is not released.
unsafeRelease :: UnsafeResource a %1 -> RIO () Source #
Given an unsafe resource, release it with the linear IO action provided when the resrouce was acquired.
unsafeAcquire :: IO (Ur a) -> (a -> IO ()) -> RIO (UnsafeResource a) Source #
Given a resource in the System.IO.Linear.IO monad, and
given a function to release that resource, provides that resource in
the RIO
monad. For example, releasing a Handle
from System.IO
would be done with fromSystemIO hClose
. Because this release function
is an input, and could be wrong, this function is unsafe.
unsafeFromSystemIOResource :: (a -> IO b) -> UnsafeResource a %1 -> RIO (Ur b, UnsafeResource a) Source #
Given a System.IO computation on an unsafe resource,
lift it to RIO
computaton on the acquired resource.
That is function of type a -> IO b
turns into a function of type
UnsafeResource a %1-> RIO (Ur b)
along with threading the UnsafeResource a
.
Note that the result b
can be used non-linearly.
unsafeFromSystemIOResource_ :: (a -> IO ()) -> UnsafeResource a %1 -> RIO (UnsafeResource a) Source #