linear-base-0.2.0: Standard library for linear types.
Safe HaskellSafe-Inferred
LanguageHaskell2010

System.IO.Resource.Linear

Description

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.Linear 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 $ 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

The Resource I/O Monad

data RIO a Source #

The resource-aware I/O monad. This monad guarantees that acquired resources are always released.

Instances

Instances details
Applicative RIO Source # 
Instance details

Defined in System.IO.Resource.Linear.Internal

Methods

pure :: a %1 -> RIO a Source #

(<*>) :: RIO (a %1 -> b) %1 -> RIO a %1 -> RIO b Source #

liftA2 :: (a %1 -> b %1 -> c) %1 -> RIO a %1 -> RIO b %1 -> RIO c Source #

Functor RIO Source # 
Instance details

Defined in System.IO.Resource.Linear.Internal

Methods

fmap :: (a %1 -> b) %1 -> RIO a %1 -> RIO b Source #

Monad RIO Source # 
Instance details

Defined in System.IO.Resource.Linear.Internal

Methods

(>>=) :: RIO a %1 -> (a %1 -> RIO b) %1 -> RIO b Source #

(>>) :: RIO () %1 -> RIO a %1 -> RIO a Source #

Applicative RIO Source # 
Instance details

Defined in System.IO.Resource.Linear.Internal

Methods

pure :: a -> RIO a Source #

(<*>) :: RIO (a %1 -> b) %1 -> RIO a %1 -> RIO b Source #

liftA2 :: (a %1 -> b %1 -> c) -> RIO a %1 -> RIO b %1 -> RIO c Source #

Functor RIO Source # 
Instance details

Defined in System.IO.Resource.Linear.Internal

Methods

fmap :: (a %1 -> b) -> RIO a %1 -> RIO b Source #

Monoid a => Monoid (RIO a) Source # 
Instance details

Defined in System.IO.Resource.Linear.Internal

Methods

mempty :: RIO a Source #

Semigroup a => Semigroup (RIO a) Source # 
Instance details

Defined in System.IO.Resource.Linear.Internal

Methods

(<>) :: RIO a %1 -> RIO a %1 -> RIO a Source #

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

data IOMode #

Instances

Instances details
Enum IOMode

Since: base-4.2.0.0

Instance details

Defined in GHC.IO.IOMode

Ix IOMode

Since: base-4.2.0.0

Instance details

Defined in GHC.IO.IOMode

Read IOMode

Since: base-4.2.0.0

Instance details

Defined in GHC.IO.IOMode

Show IOMode

Since: base-4.2.0.0

Instance details

Defined in GHC.IO.IOMode

Eq IOMode

Since: base-4.2.0.0

Instance details

Defined in GHC.IO.IOMode

Methods

(==) :: IOMode -> IOMode -> Bool #

(/=) :: IOMode -> IOMode -> Bool #

Ord IOMode

Since: base-4.2.0.0

Instance details

Defined in GHC.IO.IOMode

Working with Handles

hClose :: Handle %1 -> RIO () Source #

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.