HORIZON HASKELLDocslts/ghc-10.0.x8fef28d2026-11-02Search packagesCtrl K
Theme: |

GHC 10.0.0.20260917 · lts/ghc-10.0.x · 8fef28d · 2026-11-02

Moduleturtle-1.6.2Haskell2010

Turtle.Shell

You can think of Shell as [] + IO + Managed. In fact, you can embed all three of them within a Shell:

select ::        [a] -> Shell a
liftIO ::      IO a  -> Shell a
using  :: Managed a  -> Shell a

Those three embeddings obey these laws:

do { x <- select m; select (f x) } = select (do { x <- m; f x })
do { x <- liftIO m; liftIO (f x) } = liftIO (do { x <- m; f x })
do { x <- with   m; using  (f x) } = using  (do { x <- m; f x })

select (return x) = return x
liftIO (return x) = return x
using  (return x) = return x

... and select obeys these additional laws:

select xs <|> select ys = select (xs <|> ys)
select empty = empty

You typically won't build Shells using the Shell constructor. Instead, use these functions to generate primitive Shells:

Then use these classes to combine those primitive Shells into larger Shells:

If you still insist on building your own Shell from scratch, then the Shell you build must satisfy this law:

-- For every shell `s`:
_foldShell s (FoldShell step begin done) = do
    x' <- _foldShell s (FoldShell step begin return)
    done x'

... which is a fancy way of saying that your Shell must call 'begin' exactly once when it begins and call 'done' exactly once when it ends.

Contents
  1. Shell
  2. Embeddings
Synopsis
  • Packageturtle-1.6.2
  • Exports14
  • LanguageHaskell2010
  • LicenceBSD-3-Clause
  • SourceShell.hs

Shell

newtypenewtype Shell a

A (Shell a) is a protected stream of a's with side effects

Constructors

Instances14Monad, Functor, MonadFail, Applicative, Alternative, MonadPlus, …
value_Shell :: (forall r. FoldM IO a r -> IO r) -> Shell a

Provided for ease of migration from versions of turtle-1.4.* and older

valuereduce :: MonadIO io => Fold a b -> Shell a -> io b

Flipped version of fold. Useful for reducing a stream of data

Example

Sum a Shell of numbers:

Example1 expression
select [1, 2, 3] & reduce Fold.sum6

Embeddings

methodliftIO :: IO a -> m a

Lift a computation from the IO monad. This allows us to run IO computations in any monadic stack, so long as it supports these kinds of operations (i.e. IO is the base monad for the stack).

Example
import Control.Monad.Trans.State -- from the "transformers" library

printState :: Show s => StateT s IO ()
printState = do
  state <- get
  liftIO $ print state

Had we omitted liftIO, we would have ended up with this error:

• Couldn't match type ‘IO’ with ‘StateT s IO’
 Expected type: StateT s IO ()
   Actual type: IO ()

The important part here is the mismatch between StateT s IO () and IO ().

Luckily, we know of a function that takes an IO a and returns an (m a): liftIO, enabling us to run the program and see the expected results:

> evalStateT printState "hello"
"hello"

> evalStateT printState 3
3