├── .github └── workflows │ └── build.yml ├── .gitignore ├── README.md ├── bower.json ├── examples └── Example.purs ├── package.json └── src ├── Pipes.purs └── Pipes ├── Core.purs ├── Internal.purs ├── ListT.purs └── Prelude.purs /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | branches: [master] 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | 16 | - uses: actions/cache@v2 17 | with: 18 | path: | 19 | output 20 | node_modules 21 | bower_components 22 | key: build-artifacts-v1-${{ hashFiles('package.json', 'bower.json') }} 23 | 24 | - uses: actions/setup-node@v1 25 | with: 26 | node-version: 14 27 | 28 | - run: npm i 29 | 30 | - run: npm run build 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.sw[a-z] 2 | *.un~ 3 | /bower_components/ 4 | /node_modules/ 5 | /.pulp-cache/ 6 | /output/ 7 | /.psci* 8 | /src/.webpack.js 9 | /docs/ 10 | /.psc-ide-port 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![build](https://github.com/felixSchl/purescript-pipes/actions/workflows/build.yml/badge.svg)](https://github.com/felixSchl/purescript-pipes/actions/workflows/build.yml) 2 | 3 | # Purescript pipes 4 | 5 | > Port of the haskell pipes library by Gabriel Gonzalez to purescript: 6 | > https://hackage.haskell.org/package/pipes 7 | 8 | ## Thanks to 9 | 10 | * @scott-christopher for porting `ListT` and writing the `MonadError`, 11 | `MonadWriter`, `MonadPlus` and `Alternative` instances for `Proxy`! 12 | 13 | ## How-To 14 | 15 | For an in-depth overview of pipes follow the tutorial that comes with the 16 | Haskell pipes library. The concepts apply one to one to purescript-pipes. 17 | 18 | Also have a look at the examples that come with purescript-pipes. You can run 19 | them using `npm run example`. 20 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "purescript-pipes", 3 | "version": "2.0.0", 4 | "moduleType": ["node"], 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/felixschl/purescript-pipes.git" 8 | }, 9 | "license": "MIT", 10 | "ignore": ["**/.*", "node_modules", "bower_components", "output"], 11 | "dependencies": { 12 | "purescript-transformers": "^6.0.0", 13 | "purescript-tuples": "^7.0.0", 14 | "purescript-lists": "^7.0.0", 15 | "purescript-tailrec": "^6.0.0", 16 | "purescript-mmorph": "^7.0.0", 17 | "purescript-prelude": "^6.0.0", 18 | "purescript-aff": "^7.0.0" 19 | }, 20 | "devDependencies": { 21 | "purescript-console": "^6.0.0", 22 | "purescript-random": "^6.0.0" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /examples/Example.purs: -------------------------------------------------------------------------------- 1 | module Example where 2 | 3 | import Prelude 4 | 5 | import Effect (Effect) 6 | import Effect.Class (liftEffect) 7 | import Effect.Class.Console (log) 8 | import Effect.Random (randomInt) 9 | import Pipes (yield, for) 10 | import Pipes.Core (runEffect, Producer_) 11 | 12 | pipedRandomInt 13 | :: Int 14 | -> Int 15 | -> Producer_ String Effect Int 16 | pipedRandomInt x y = do 17 | yield $ "Generating an Int between " <> show x <> " and " <> show y <> "..." 18 | r <- liftEffect $ randomInt x y 19 | yield $ "Generated " <> show r 20 | pure r 21 | 22 | main :: Effect Unit 23 | main = 24 | let go = pipedRandomInt 1 10 25 | in do 26 | r <- runEffect $ for go (log <<< ("Log: " <> _)) 27 | log $ "Result: " <> show r 28 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "postinstall": "bower install", 5 | "build": "pulp build && rimraf docs && pulp docs", 6 | "example": "pulp run -I examples -I src -I bower_components -m Example" 7 | }, 8 | "devDependencies": { 9 | "bower": "^1.8.12", 10 | "pulp": "^16.0.0-0", 11 | "purescript": "^0.15.0-0", 12 | "rimraf": "^3.0.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Pipes.purs: -------------------------------------------------------------------------------- 1 | module Pipes where 2 | 3 | import Prelude (class Monad, Unit, const, flip, pure, unit, (*>), (>>=)) 4 | import Pipes.Core (Consumer_, Pipe, Producer, Producer_, closed, pull, request, respond, (+>>), (//>), (/>/), (>\\)) 5 | import Pipes.Internal (Proxy(..)) 6 | import Data.Foldable (class Foldable) 7 | import Data.Tuple (Tuple(..)) 8 | import Data.Either (Either(..)) 9 | import Data.Foldable as F 10 | 11 | infixl 4 composeLoopBodies' as <~ 12 | infixr 4 composeLoopBodies as ~> 13 | infixr 5 replaceAwait as >~ 14 | infixl 5 replaceAwait' as ~< 15 | infixl 7 composePipes as >-> 16 | infixr 7 composePipes' as <-< 17 | 18 | for 19 | :: forall a b b' c c' x x' m 20 | . Monad m 21 | => Proxy x' x b' b m a 22 | -> (b -> Proxy x' x c' c m b') 23 | -> Proxy x' x c' c m a 24 | for = (//>) 25 | 26 | -- (~>) 27 | composeLoopBodies 28 | :: forall a a' b b' c c' x x' m 29 | . Monad m 30 | => (a -> Proxy x' x b' b m a') 31 | -> (b -> Proxy x' x c' c m b') 32 | -> (a -> Proxy x' x c' c m a') 33 | composeLoopBodies = (/>/) 34 | 35 | -- (<~) 36 | composeLoopBodies' 37 | :: forall a a' b b' c c' x x' m 38 | . Monad m 39 | => (b -> Proxy x' x c' c m b') 40 | -> (a -> Proxy x' x b' b m a') 41 | -> (a -> Proxy x' x c' c m a') 42 | composeLoopBodies' = flip composeLoopBodies 43 | 44 | await :: forall a m. Monad m => Consumer_ a m a 45 | await = request unit 46 | 47 | -- (~<) 48 | replaceAwait 49 | :: forall a a' b y y' c m 50 | . Monad m 51 | => Proxy a' a y' y m b 52 | -> Proxy Unit b y' y m c 53 | -> Proxy a' a y' y m c 54 | replaceAwait p1 p2 = const p1 >\\ p2 55 | 56 | -- (>~) 57 | replaceAwait' 58 | :: forall a a' b y y' c m 59 | . Monad m 60 | => Proxy Unit b y' y m c 61 | -> Proxy a' a y' y m b 62 | -> Proxy a' a y' y m c 63 | replaceAwait' = flip replaceAwait 64 | 65 | cat :: forall a m r. Monad m => Pipe a a m r 66 | cat = pull unit 67 | 68 | -- (>->) 69 | composePipes 70 | :: forall a a' b c c' m r 71 | . Monad m 72 | => Proxy a' a Unit b m r 73 | -> Proxy Unit b c' c m r 74 | -> Proxy a' a c' c m r 75 | composePipes p1 p2 = const p1 +>> p2 76 | 77 | -- (<-<) 78 | composePipes' 79 | :: forall a a' b c c' m r 80 | . Monad m 81 | => Proxy Unit b c' c m r 82 | -> Proxy a' a Unit b m r 83 | -> Proxy a' a c' c m r 84 | composePipes' = flip composePipes 85 | 86 | yield :: forall m a. Monad m => a -> Producer_ a m Unit 87 | yield = respond 88 | 89 | {-| Consume the first value from a `Producer` 90 | `next` either fails with a `Left` if the `Producer` terminates or succeeds 91 | with a `Right` providing the next value and the remainder of the `Producer`. 92 | -} 93 | next :: forall a m r. Monad m => Producer a m r -> m (Either r (Tuple a (Producer a m r))) 94 | next = go 95 | where 96 | go p = case p of 97 | Request v _ -> closed v 98 | Respond a fu -> pure (Right (Tuple a (fu unit))) 99 | M m -> m >>= go 100 | Pure r -> pure (Left r) 101 | 102 | -- | Convert a `F.Foldable` to a `Producer` 103 | each :: forall a f m. Monad m => Foldable f => f a -> Producer_ a m Unit 104 | each xs = F.foldr (\a p -> yield a *> p) (pure unit) xs 105 | 106 | -- | Discards a value 107 | discard :: forall a m. Monad m => a -> m Unit 108 | discard _ = pure unit 109 | -------------------------------------------------------------------------------- /src/Pipes/Core.purs: -------------------------------------------------------------------------------- 1 | module Pipes.Core ( 2 | -- * Proxy Monad Transformer 3 | runEffect 4 | , runEffectRec 5 | 6 | -- * Categories 7 | 8 | -- ** Respond 9 | , respond 10 | , composeResponse' 11 | , (/>/) 12 | , composeResponse 13 | , (//>) 14 | 15 | -- ** Request 16 | , request 17 | , composeRequest' 18 | , (\>\) 19 | , composeRequest 20 | , (>\\) 21 | 22 | -- ** Push 23 | , push 24 | , composePush 25 | , (>~>) 26 | , composePush' 27 | , (>>~) 28 | 29 | -- ** Pull 30 | , pull 31 | , composePull 32 | , (>+>) 33 | , composePull' 34 | , (+>>) 35 | 36 | -- ** Reflect 37 | , reflect 38 | 39 | -- * Concrete Type Synonyms 40 | , Effect 41 | , Producer 42 | , Pipe 43 | , Consumer 44 | , Client 45 | , Server 46 | , Effect_ 47 | , Producer_ 48 | , Consumer_ 49 | , Client_ 50 | , Server_ 51 | 52 | -- * Flipped operators 53 | , flippedComposeResponse' 54 | , (\<\) 55 | , flippedComposeRequest' 56 | , (/), (<<<), (>>=)) 75 | import Pipes.Internal (Proxy(..), X, closed) 76 | import Pipes.Internal (Proxy (), X(), closed) as I 77 | import Control.Monad.Rec.Class (class MonadRec, tailRecM, Step(Loop, Done)) 78 | 79 | type Effect = Proxy X Unit Unit X 80 | type Producer b = Proxy X Unit Unit b 81 | type Pipe a b = Proxy Unit a Unit b 82 | type Consumer a = Proxy Unit a Unit X 83 | type Client a' a = Proxy a' a Unit X 84 | type Server b' b = Proxy X Unit b' b 85 | 86 | type Effect_ m r = forall x' x y' y. Proxy x' x y' y m r 87 | type Producer_ b m r = forall x' x. Proxy x' x Unit b m r 88 | type Consumer_ a m r = forall y' y. Proxy Unit a y' y m r 89 | type Server_ b' b m r = forall x' x. Proxy x' x b' b m r 90 | type Client_ a' a m r = forall y' y. Proxy a' a y' y m r 91 | 92 | runEffect :: forall m r. Monad m => Effect m r -> m r 93 | runEffect = go 94 | where 95 | go p = case p of 96 | Request v _ -> closed v 97 | Respond v _ -> closed v 98 | M m -> m >>= go 99 | Pure r -> pure r 100 | 101 | runEffectRec :: forall m r. (MonadRec m) => Effect m r -> m r 102 | runEffectRec = tailRecM go 103 | where 104 | go (Request v _) = Done <$> closed v 105 | go (Respond v _) = Done <$> closed v 106 | go (Pure r) = pure (Done r) 107 | go (M mr) = Loop <$> mr 108 | 109 | respond :: forall m a a' x x'. Monad m => a -> Proxy x' x a' a m a' 110 | respond a = Respond a Pure 111 | 112 | infixl 4 composeResponse as //> 113 | infixr 4 composeResponse' as />/ 114 | infixl 5 composeRequest as >\\ 115 | infixr 4 composeRequest' as \>\ 116 | infixr 6 composePull' as +>> 117 | infixl 7 composePull as >+> 118 | infixl 7 composePush' as >>~ 119 | infixr 8 composePush as >~> 120 | infixl 4 flippedComposeResponse' as \<\ 121 | infixr 4 flippedComposeRequest' as / Proxy x' x b' b m a' 133 | -> (b -> Proxy x' x c' c m b') 134 | -> Proxy x' x c' c m a' 135 | composeResponse p0 fb = go p0 136 | where 137 | go p = case p of 138 | Request x' fx -> Request x' (go <<< fx) 139 | Respond b fb' -> fb b >>= go <<< fb' 140 | M m -> M (go <$> m) 141 | Pure a -> Pure a 142 | 143 | composeResponse' 144 | :: forall m x x' a a' b b' c c' 145 | . Monad m 146 | => (a -> Proxy x' x b' b m a') 147 | -> (b -> Proxy x' x c' c m b') 148 | -> (a -> Proxy x' x c' c m a') 149 | composeResponse' fa fb a = fa a //> fb 150 | 151 | request :: forall a a' y y' m. Monad m => a' -> Proxy a' a y' y m a 152 | request a' = Request a' Pure 153 | 154 | -- (>\\) 155 | composeRequest 156 | :: forall a a' b b' c y y' m 157 | . Monad m 158 | => (b' -> Proxy a' a y' y m b) 159 | -> Proxy b' b y' y m c 160 | -> Proxy a' a y' y m c 161 | composeRequest fb' p0 = go p0 162 | where 163 | go p = case p of 164 | Request b' fb -> fb' b' >>= go <<< fb 165 | Respond x fx' -> Respond x (go <<< fx') 166 | M m -> M (go <$> m) 167 | Pure a -> Pure a 168 | 169 | -- (\>\) 170 | composeRequest' 171 | :: forall a a' b b' c c' y y' m 172 | . Monad m 173 | => (b' -> Proxy a' a y' y m b) 174 | -> (c' -> Proxy b' b y' y m c) 175 | -> (c' -> Proxy a' a y' y m c) 176 | composeRequest' fb' fc' c' = fb' `composeRequest` fc' c' 177 | 178 | pull :: forall a a' m r. Monad m => a' -> Proxy a' a a' a m r 179 | pull = go 180 | where 181 | go a' = Request a' (\a -> Respond a go) 182 | 183 | composePull 184 | :: forall a a' b b' c c' _c' m r 185 | . Monad m 186 | => ( b' -> Proxy a' a b' b m r) 187 | -> (_c' -> Proxy b' b c' c m r) 188 | -> (_c' -> Proxy a' a c' c m r) 189 | composePull fb' fc' c' = fb' +>> fc' c' 190 | 191 | composePull' 192 | :: forall a a' b b' c c' m r 193 | . Monad m 194 | => (b' -> Proxy a' a b' b m r) 195 | -> Proxy b' b c' c m r 196 | -> Proxy a' a c' c m r 197 | composePull' fb' p = case p of 198 | Request b' fb -> fb' b' >>~ fb 199 | Respond c fc' -> Respond c ((fb' +>> _) <<< fc') 200 | M m -> M ((fb' +>> _) <$> m) 201 | Pure r -> Pure r 202 | 203 | push :: forall a a' m r. Monad m => a -> Proxy a' a a' a m r 204 | push = go 205 | where 206 | go a = Respond a (\a' -> Request a' go) 207 | 208 | composePush 209 | :: forall _a a a' b b' c c' m r 210 | . Monad m 211 | => (_a -> Proxy a' a b' b m r) 212 | -> ( b -> Proxy b' b c' c m r) 213 | -> (_a -> Proxy a' a c' c m r) 214 | composePush fa fb a = fa a >>~ fb 215 | 216 | composePush' 217 | :: forall a a' b b' c c' m r 218 | . Monad m 219 | => Proxy a' a b' b m r 220 | -> (b -> Proxy b' b c' c m r) 221 | -> Proxy a' a c' c m r 222 | composePush' p fb = case p of 223 | Request a' fa -> Request a' (\a -> fa a >>~ fb) 224 | Respond b fb' -> fb' +>> fb b 225 | M m -> M (m >>= \p' -> pure (p' >>~ fb)) 226 | Pure r -> Pure r 227 | 228 | reflect 229 | :: forall a a' b b' m r 230 | . Monad m 231 | => Proxy a' a b' b m r -> Proxy b b' a a' m r 232 | reflect = go 233 | where 234 | go p = case p of 235 | Request a' fa -> Respond a' (go <<< fa) 236 | Respond b fb' -> Request b (go <<< fb') 237 | M m -> M (go <$> m) 238 | Pure r -> Pure r 239 | 240 | -- | Equivalent to ('/>/') with the arguments flipped 241 | flippedComposeResponse' 242 | :: forall m x x' a a' b b' c c' 243 | . Monad m 244 | => (b -> Proxy x' x c' c m b') 245 | -> (a -> Proxy x' x b' b m a') 246 | -> (a -> Proxy x' x c' c m a') 247 | flippedComposeResponse' p1 p2 = p2 />/ p1 248 | 249 | -- | Equivalent to ('\>\') with the arguments flipped 250 | flippedComposeRequest' 251 | :: forall a a' b b' c c' y y' m 252 | . Monad m 253 | => (c' -> Proxy b' b y' y m c) 254 | -> (b' -> Proxy a' a y' y m b) 255 | -> (c' -> Proxy a' a y' y m c) 256 | flippedComposeRequest' p1 p2 = p2 \>\ p1 257 | 258 | -- | Equivalent to ('>~>') with the arguments flipped 259 | flippedComposePush 260 | :: forall a a' b b' c c' m r 261 | . Monad m 262 | => (b -> Proxy b' b c' c m r) 263 | -> (a -> Proxy a' a b' b m r) 264 | -> (a -> Proxy a' a c' c m r) 265 | flippedComposePush p1 p2 = p2 >~> p1 266 | 267 | -- | Equivalent to ('>+>') with the arguments flipped 268 | flippedComposePull 269 | :: forall a a' b b' c c' m r 270 | . Monad m 271 | => (c' -> Proxy b' b c' c m r) 272 | -> (b' -> Proxy a' a b' b m r) 273 | -> (c' -> Proxy a' a c' c m r) 274 | flippedComposePull p1 p2 = p2 >+> p1 275 | 276 | -- | Equivalent to ('//>') with the arguments flipped 277 | flippedComposeResponse 278 | :: forall m x x' a' b b' c c' 279 | . Monad m 280 | => (b -> Proxy x' x c' c m b') 281 | -> Proxy x' x b' b m a' 282 | -> Proxy x' x c' c m a' 283 | flippedComposeResponse f p = p //> f 284 | 285 | -- | Equivalent to ('>\\') with the arguments flipped 286 | flippedComposeRequest 287 | :: forall a a' b b' c y y' m 288 | . Monad m 289 | => Proxy b' b y' y m c 290 | -> (b' -> Proxy a' a y' y m b) 291 | -> Proxy a' a y' y m c 292 | flippedComposeRequest p f = f >\\ p 293 | 294 | -- | Equivalent to ('>>~') with the arguments flipped 295 | flippedComposePush' 296 | :: forall a a' b b' c c' m r 297 | . Monad m 298 | => (b -> Proxy b' b c' c m r) 299 | -> Proxy a' a b' b m r 300 | -> Proxy a' a c' c m r 301 | flippedComposePush' k p = p >>~ k 302 | 303 | -- | Equivalent to ('+>>') with the arguments flipped 304 | flippedComposePull' 305 | :: forall a a' b b' c c' m r 306 | . Monad m 307 | => Proxy b' b c' c m r 308 | -> (b' -> Proxy a' a b' b m r) 309 | -> Proxy a' a c' c m r 310 | flippedComposePull' k p = p +>> k 311 | -------------------------------------------------------------------------------- /src/Pipes/Internal.purs: -------------------------------------------------------------------------------- 1 | module Pipes.Internal where 2 | 3 | import Prelude 4 | 5 | import Control.Alt (class Alt, (<|>)) 6 | import Control.Alternative (class Alternative) 7 | import Control.Monad.Except.Trans (class MonadError, catchError, class MonadThrow, throwError) 8 | import Control.Monad.Morph (class MFunctor, class MMonad) 9 | import Control.Monad.Reader.Class (class MonadAsk, class MonadReader, local, ask) 10 | import Control.Monad.Rec.Class (class MonadRec, Step(Done, Loop)) 11 | import Control.Monad.State.Class (class MonadState, state) 12 | import Control.Monad.Trans.Class (class MonadTrans, lift) 13 | import Control.Monad.Writer.Class (class MonadWriter, class MonadTell, listen, pass, tell) 14 | import Control.MonadPlus (class MonadPlus) 15 | import Control.Plus (class Plus, empty) 16 | import Data.Tuple (Tuple(Tuple)) 17 | import Effect.Aff.Class (class MonadAff, liftAff) 18 | import Effect.Class (class MonadEffect, liftEffect) 19 | 20 | data Proxy a' a b' b m r 21 | = Request a' (a -> Proxy a' a b' b m r) 22 | | Respond b (b' -> Proxy a' a b' b m r) 23 | | M (m (Proxy a' a b' b m r)) 24 | | Pure r 25 | 26 | instance functorProxy :: (Monad m) => Functor (Proxy a' a b' b m) where 27 | map f p0 = go p0 where 28 | go p = case p of 29 | Request a' fa -> Request a' \x -> go (fa x) 30 | Respond b fb' -> Respond b \x -> go (fb' x) 31 | M m -> M (m >>= \v -> pure (go v)) 32 | Pure r -> Pure (f r) 33 | 34 | instance applyProxy :: (Monad m) => Apply (Proxy a' a b' b m) where 35 | apply pf0 px = go pf0 where 36 | go pf = case pf of 37 | Request a' fa -> Request a' \x -> go (fa x) 38 | Respond b fb' -> Respond b \x -> go (fb' x) 39 | M m -> M (m >>= \v -> pure (go v)) 40 | Pure f -> f <$> px 41 | 42 | instance applicativeProxy :: (Monad m) => Applicative (Proxy a' a b' b m) where 43 | pure = Pure 44 | 45 | instance bindProxy :: (Monad m) => Bind (Proxy a' a b' b m) where 46 | bind p0 f = go p0 where 47 | go p = case p of 48 | Request a' fa -> Request a' \x -> go (fa x) 49 | Respond b fb' -> Respond b \x -> go (fb' x) 50 | M m -> M (m >>= \v -> pure (go v)) 51 | Pure r -> f r 52 | 53 | instance monadProxy :: (Monad m) => Monad (Proxy a' a b' b m) 54 | 55 | instance monoidProxy :: (Monad m, Monoid r) => Monoid (Proxy a' a b' b m r) where 56 | mempty = Pure mempty 57 | 58 | instance semigroupProxy :: (Monad m, Semigroup r) => Semigroup (Proxy a' a b' b m r) where 59 | append p1 p2 = go p1 where 60 | go p = case p of 61 | Request a' fa -> Request a' \x -> go (fa x) 62 | Respond b fb' -> Respond b \x -> go (fb' x) 63 | M m -> M (m >>= \v -> pure (go v)) 64 | Pure r1 -> (r1 <> _) <$> p2 65 | 66 | instance monadTransProxy :: MonadTrans (Proxy a' a b' b) where 67 | lift m = M (Pure <$> m) 68 | 69 | instance proxyMFunctor :: MFunctor (Proxy a' a b' b) where 70 | hoist nat p0 = go (observe p0) 71 | where 72 | go p = case p of 73 | Request a' fa -> Request a' \x -> go (fa x) 74 | Respond b fb' -> Respond b \x -> go (fb' x) 75 | M m -> M (nat (m >>= \p' -> pure (go p'))) 76 | Pure r -> Pure r 77 | 78 | instance proxyMMonad :: MMonad (Proxy a' a b' b) where 79 | embed f = go 80 | where 81 | go p = case p of 82 | Request a' fa -> Request a' \x -> go (fa x) 83 | Respond b fb' -> Respond b \x -> go (fb' x) 84 | M m -> f m >>= go 85 | Pure r -> Pure r 86 | 87 | instance proxyMonadEffect :: MonadEffect m => MonadEffect (Proxy a' a b' b m) where 88 | liftEffect m = M (liftEffect (m >>= \r -> pure (Pure r))) 89 | 90 | instance proxyMonadAff :: MonadAff m => MonadAff (Proxy a' a b' b m) where 91 | liftAff m = M (liftAff (m >>= \r -> pure (Pure r))) 92 | 93 | instance proxyMonadAsk :: MonadAsk r m => MonadAsk r (Proxy a' a b' b m) where 94 | ask = lift ask 95 | 96 | instance proxyMonadReader :: MonadReader r m => MonadReader r (Proxy a' a b' b m) where 97 | local f = go 98 | where 99 | go p = case p of 100 | Request a' fa -> Request a' (\a -> go (fa a )) 101 | Respond b fb' -> Respond b (\b' -> go (fb' b')) 102 | Pure r -> Pure r 103 | M m -> M (local f m >>= \r -> pure (go r)) 104 | 105 | instance proxyMonadState :: MonadState s m => MonadState s (Proxy a' a b' b m) where 106 | state = lift <<< state 107 | 108 | instance proxyMonadTell :: (Monoid w, MonadTell w m) => MonadTell w (Proxy a' a b' b m) where 109 | tell = lift <<< tell 110 | 111 | instance proxyMonadWriter :: (Monoid w, MonadWriter w m) => MonadWriter w (Proxy a' a b' b m) where 112 | listen p0 = go p0 mempty 113 | where 114 | go p w = case p of 115 | Request a' fa -> Request a' (\a -> go (fa a ) w) 116 | Respond b fb' -> Respond b (\b' -> go (fb' b') w) 117 | Pure r -> Pure (Tuple r w) 118 | M m -> M (do 119 | Tuple p' w' <- listen m 120 | pure (go p' (append w w'))) 121 | 122 | pass p0 = go p0 mempty 123 | where 124 | go p w = case p of 125 | Request a' fa -> Request a' (\a -> go (fa a ) w) 126 | Respond b fb' -> Respond b (\b' -> go (fb' b') w) 127 | Pure (Tuple r f) -> M (pass (pure (Tuple (Pure r) \_ -> f w))) 128 | M m -> M (do 129 | Tuple p' w' <- listen m 130 | pure (go p' (append w w'))) 131 | 132 | instance proxyAlt :: (MonadPlus m) => Alt (Proxy a' a b' b m) where 133 | alt (Request a' fa) p = Request a' (\a -> (fa a) <|> p) 134 | alt (Respond b fb') p = Respond b (\b' -> (fb' b') <|> p) 135 | alt (Pure r) _ = Pure r 136 | alt (M m) p = M ((do 137 | p' <- m 138 | pure (p' <|> p)) <|> pure p) 139 | 140 | instance proxyPlus :: (MonadPlus m) => Plus (Proxy a' a b' b m) where 141 | empty = lift empty 142 | 143 | instance proxyAlternative :: (MonadPlus m) => Alternative (Proxy a' a b' b m) 144 | 145 | -- XXX: these won't compile 146 | -- instance proxyMonadPlus :: (MonadPlus m) => MonadPlus (Proxy a' a b' b m) 147 | -- instance proxyMonadZero :: (MonadZero m) => MonadZero (Proxy a' a b' b m) 148 | 149 | instance proxyMonadThrow :: (MonadThrow e m) => MonadThrow e (Proxy a' a b' b m) where 150 | throwError = lift <<< throwError 151 | 152 | instance proxyMonadError :: (MonadError e m) => MonadError e (Proxy a' a b' b m) where 153 | catchError (Request a' fa) f = Request a' (\a -> catchError (fa a ) f) 154 | catchError (Respond b fb') f = Respond b (\b' -> catchError (fb' b') f) 155 | catchError (Pure r) _ = Pure r 156 | catchError (M m) f = M ((do 157 | p' <- m 158 | pure (catchError p' f)) `catchError` (pure <<< f)) 159 | 160 | instance monadRecProxy :: Monad m => MonadRec (Proxy a' a b' b m) where 161 | tailRecM f a0 = go (f a0) 162 | where 163 | go = case _ of 164 | Pure (Loop a) -> go (f a) 165 | Pure (Done b) -> Pure b 166 | M m -> M $ m >>= \v -> pure (go v) 167 | Request a' fa -> Request a' \x -> go (fa x) 168 | Respond b fb' -> Respond b \x -> go (fb' x) 169 | 170 | observe :: forall m a' a b' b r 171 | . Monad m => Proxy a' a b' b m r -> Proxy a' a b' b m r 172 | observe p0 = M (go p0) where 173 | go p = case p of 174 | Request a' fa -> pure (Request a' (observe <<< fa)) 175 | Respond b fb' -> pure (Respond b (observe <<< fb')) 176 | M m -> m >>= go 177 | Pure r -> pure (Pure r) 178 | 179 | newtype X = X X 180 | 181 | closed :: forall a. X -> a 182 | closed (X x) = closed x 183 | -------------------------------------------------------------------------------- /src/Pipes/ListT.purs: -------------------------------------------------------------------------------- 1 | module Pipes.ListT where 2 | 3 | import Prelude hiding (discard) 4 | 5 | import Control.Alt (class Alt, alt) 6 | import Control.Alternative (class Alternative) 7 | import Control.Monad.Except.Trans (ExceptT, runExceptT, class MonadError, class MonadTrans, lift, catchError, class MonadThrow, throwError) 8 | import Control.Monad.Maybe.Trans (MaybeT, runMaybeT) 9 | import Control.Monad.Reader.Class (class MonadAsk, class MonadReader, local, ask) 10 | import Control.Monad.Rec.Class (class MonadRec) 11 | import Control.Monad.State.Class (class MonadState, state) 12 | import Control.Monad.Writer.Class (class MonadTell, class MonadWriter, listen, pass, tell) 13 | import Control.Plus (class Plus, empty) 14 | import Data.Either (Either(Left, Right)) 15 | import Data.Maybe (Maybe(Nothing, Just)) 16 | import Data.Tuple (Tuple(Tuple)) 17 | import Effect.Class (class MonadEffect, liftEffect) 18 | import Pipes (discard, for, yield) 19 | import Pipes.Core (Producer, Producer_, runEffect, runEffectRec, (>\\)) 20 | import Pipes.Internal (Proxy(Pure, M, Respond, Request)) 21 | 22 | 23 | newtype ListT m a = Select (Producer a m Unit) 24 | 25 | enumerate :: forall a m. ListT m a -> Producer a m Unit 26 | enumerate (Select l) = l 27 | 28 | runListT :: forall a m. (Monad m) => ListT m a -> m Unit 29 | runListT l = runEffect (enumerate (l *> empty)) 30 | 31 | runListTRec :: forall a m. (MonadRec m) => ListT m a -> m Unit 32 | runListTRec l = runEffectRec (enumerate (l *> empty)) 33 | 34 | every :: forall a m t. Monad m => Enumerable t => t m a -> Producer_ a m Unit 35 | every it = discard >\\ enumerate (toListT it) 36 | 37 | instance listTFunctor :: (Monad m) => Functor (ListT m) where 38 | map f (Select p) = Select (for p (yield <<< f)) 39 | 40 | instance listTApply :: (Monad m) => Apply (ListT m) where 41 | apply (Select mf) (Select mx) = Select (for mf (\f -> for mx (\x -> yield (f x)))) 42 | 43 | instance listTApplicative :: (Monad m) => Applicative (ListT m) where 44 | pure = Select <<< yield 45 | 46 | instance listTBind :: (Monad m) => Bind (ListT m) where 47 | bind (Select p1) f = Select (for p1 (enumerate <<< f)) 48 | 49 | instance listTMonad :: (Monad m) => Monad (ListT m) 50 | 51 | instance listTMonadTrans :: MonadTrans ListT where 52 | lift m = Select (lift m >>= yield) 53 | 54 | instance listTAlt :: (Monad m) => Alt (ListT m) where 55 | alt (Select p1) (Select p2) = Select (p1 *> p2) 56 | 57 | instance listTPlus :: (Monad m) => Plus (ListT m) where 58 | empty = Select (pure unit) 59 | 60 | instance listTAlternative :: (Monad m) => Alternative (ListT m) 61 | 62 | -- XXX: these won't compile 63 | -- instance listTMonadPlus :: (Monad m) => MonadPlus (ListT m) 64 | -- instance listTMonadZero :: (Monad m) => MonadZero (ListT m) 65 | 66 | instance listTMonadEffect :: (MonadEffect m) => MonadEffect (ListT m) where 67 | liftEffect = lift <<< liftEffect 68 | 69 | instance listTSemigroup :: (Monad m) => Semigroup (ListT m a) where 70 | append = alt 71 | 72 | instance listTMonoid :: (Monad m) => Monoid (ListT m a) where 73 | mempty = empty 74 | 75 | instance listTMonadState :: (MonadState s m) => MonadState s (ListT m) where 76 | state = lift <<< state 77 | 78 | instance listTMonadTell :: (Monoid w, MonadTell w m) => MonadTell w (ListT m) where 79 | tell = lift <<< tell 80 | 81 | instance listTMonadWriter :: (Monoid w, MonadWriter w m) => MonadWriter w (ListT m) where 82 | listen (Select p) = Select (go p mempty) 83 | where 84 | go (Request a' fa) w = Request a' (\a -> go (fa a) w) 85 | go (Respond b fb') w = Respond (Tuple b w) (\b' -> go (fb' b') w) 86 | go (M m) w = M (do 87 | Tuple p' w' <- listen m 88 | pure (go p' (append w w'))) 89 | go (Pure r) _ = Pure r 90 | 91 | pass (Select p) = Select (go p mempty) 92 | where 93 | go (Request a' fa) w = Request a' (\a -> go (fa a) w) 94 | go (Respond (Tuple b f) fb') w = M (pass (pure (Tuple _1 _2))) 95 | where _1 = Respond b (\b' -> go (fb' b') (f w)) 96 | _2 = \_ -> f w 97 | go (M m) w = M (do Tuple p' w' <- listen m 98 | pure (go p' (append w w'))) 99 | go (Pure r) _ = Pure r 100 | 101 | instance listTMonadAsk :: (MonadAsk r m) => MonadAsk r (ListT m) where 102 | ask = lift ask 103 | 104 | instance listTMonadReader :: (MonadReader r m) => MonadReader r (ListT m) where 105 | local f (Select l) = Select (local f l) 106 | 107 | instance listTMonadThrow :: (MonadThrow e m) => MonadThrow e (ListT m) where 108 | throwError = lift <<< throwError 109 | 110 | instance listTMonadError :: (MonadError e m) => MonadError e (ListT m) where 111 | catchError (Select l) f = Select (l `catchError` (enumerate <<< f)) 112 | 113 | class Enumerable t where 114 | toListT :: forall a m. Monad m => t m a -> ListT m a 115 | 116 | instance listTEnumerable :: Enumerable ListT where 117 | toListT = identity 118 | 119 | instance maybeTEnumerable :: Enumerable MaybeT where 120 | toListT m = Select $ do 121 | x <- lift $ runMaybeT m 122 | case x of 123 | Nothing -> pure unit 124 | Just a -> yield a 125 | 126 | instance errorTEnumerable :: Enumerable (ExceptT e) where 127 | toListT m = Select $ do 128 | x <- lift $ runExceptT m 129 | case x of 130 | Left _ -> pure unit 131 | Right a -> yield a 132 | -------------------------------------------------------------------------------- /src/Pipes/Prelude.purs: -------------------------------------------------------------------------------- 1 | module Pipes.Prelude where 2 | 3 | import Prelude hiding (map) 4 | import Prelude as Prelude 5 | import Pipes 6 | ( (>->) 7 | , (>~) 8 | , await 9 | , each 10 | , cat 11 | , for 12 | , next 13 | , yield 14 | ) 15 | import Pipes as Pipes 16 | import Pipes.Core (Consumer_, Pipe, Producer, Producer_) 17 | import Pipes.Internal (Proxy(..), closed) 18 | import Data.List (List(..), (:)) 19 | import Data.Identity (Identity) 20 | import Data.Newtype (unwrap) 21 | import Data.Maybe (Maybe(..)) 22 | import Data.Either (Either(..)) 23 | import Data.Foldable (class Foldable) 24 | import Data.Tuple (Tuple(..)) 25 | import Control.Monad.Trans.Class (lift) 26 | 27 | -- | Repeat a monadic action indefinitely, `yield`ing each result 28 | repeatM :: forall a m r. Monad m => m a -> Producer_ a m r 29 | repeatM m = lift m >~ cat 30 | 31 | -- | Repeat a monadic action a fixed number of times, `yield`ing each result 32 | replicateM :: forall a m. Monad m => Int -> m a -> Producer_ a m Unit 33 | replicateM n m = lift m >~ take n 34 | 35 | -- | Consume all values using a monadic function 36 | mapM_ :: forall a m r. Monad m => (a -> m Unit) -> Consumer_ a m r 37 | mapM_ f = for cat (\a -> lift (f a)) 38 | 39 | -- | `discard` all incoming values 40 | drain :: forall a m r. Monad m => Consumer_ a m r 41 | drain = for cat Pipes.discard 42 | 43 | -- | Apply a function to all values flowing downstream 44 | map :: forall a b m r. Monad m => (a -> b) -> Pipe a b m r 45 | map f = for cat (\a -> yield (f a)) 46 | 47 | -- | Apply a monadic function to all values flowing downstream 48 | mapM :: forall a b m r. Monad m => (a -> m b) -> Pipe a b m r 49 | mapM f = for cat $ \a -> do 50 | b <- lift (f a) 51 | yield b 52 | 53 | -- | Convert a stream of actions to a stream of values 54 | sequence :: forall a m r. Monad m => Pipe (m a) a m r 55 | sequence = mapM identity 56 | 57 | {- | Apply a function to all values flowing downstream, and 58 | forward each element of the result. 59 | -} 60 | mapFoldable :: forall a b m t r 61 | . Monad m 62 | => Foldable t 63 | => (a -> t b) 64 | -> Pipe a b m r 65 | mapFoldable f = for cat (\a -> each (f a)) 66 | 67 | 68 | -- | `filter` only forwards values that satisfy the predicate. 69 | filter :: forall a m r. Monad m => (a -> Boolean) -> Pipe a a m r 70 | filter predicate = for cat $ \a -> when (predicate a) (yield a) 71 | 72 | -- |`filterM` only forwards values that satisfy the monadic predicate 73 | filterM :: forall a m r. Monad m => (a -> m Boolean) -> Pipe a a m r 74 | filterM predicate = for cat $ \a -> do 75 | b <- lift (predicate a) 76 | when b (yield a) 77 | 78 | -- | `take n` only allows n values to pass through 79 | take :: forall a m. Monad m => Int -> Pipe a a m Unit 80 | take = loop where 81 | loop 0 = pure unit 82 | loop n = do 83 | a <- await 84 | yield a 85 | loop (n - 1) 86 | 87 | {-| `takeWhile` allows values to pass downstream so long as they satisfy 88 | the predicate `p`. 89 | -} 90 | takeWhile :: forall a m. Monad m => (a -> Boolean) -> Pipe a a m Unit 91 | takeWhile predicate = go 92 | where 93 | go = do 94 | a <- await 95 | if (predicate a) 96 | then do 97 | yield a 98 | go 99 | else pure unit 100 | 101 | {-| `takeWhile'` is a version of `takeWhile` that returns the value failing 102 | the predicate. 103 | -} 104 | takeWhile' :: forall a m. Monad m => (a -> Boolean) -> Pipe a a m a 105 | takeWhile' predicate = go 106 | where 107 | go = do 108 | a <- await 109 | if (predicate a) 110 | then do 111 | yield a 112 | go 113 | else pure a 114 | 115 | -- | drop discards n values going downstream 116 | drop :: forall a m r. Monad m => Int -> Pipe a a m r 117 | drop = loop 118 | where 119 | loop 0 = cat 120 | loop n = do 121 | _ <- await 122 | loop (n-1) 123 | 124 | {-| dropWhile discards values going downstream until one violates the 125 | predicate p. 126 | -} 127 | dropWhile :: forall a m r. Monad m => (a -> Boolean) -> Pipe a a m r 128 | dropWhile predicate = go 129 | where 130 | go = do 131 | a <- await 132 | if (predicate a) 133 | then go 134 | else do 135 | yield a 136 | cat 137 | 138 | -- | Flatten all 'Foldable' elements flowing downstream 139 | concat :: forall a m f r. Monad m => Foldable f => Pipe (f a) a m r 140 | concat = for cat each 141 | 142 | -- | Outputs the indices of all elements that satisfied the predicate 143 | findIndices :: forall a m r. Monad m => (a -> Boolean) -> Pipe a Int m r 144 | findIndices predicate = go 0 145 | where 146 | go n = do 147 | a <- await 148 | when (predicate a) (yield n) 149 | go $ n + 1 150 | 151 | -- | Left scan 152 | scan 153 | :: forall a b x m r 154 | . Monad m 155 | => (x -> a -> x) -> x -> (x -> b) -> Pipe a b m r 156 | scan step begin done = go begin 157 | where 158 | go x = do 159 | yield (done x) 160 | a <- await 161 | let x' = step x a 162 | go $ x' 163 | 164 | -- | Monadic left scan 165 | scanM 166 | :: forall a b x m r 167 | . Monad m 168 | => (x -> a -> m x) -> m x -> (x -> m b) -> Pipe a b m r 169 | scanM step begin done = do 170 | x <- lift begin 171 | go x 172 | where 173 | go x = do 174 | b <- lift (done x) 175 | yield b 176 | a <- await 177 | x' <- lift (step x a) 178 | go $ x' 179 | 180 | -- | Apply an action to all values flowing downstream 181 | chain :: forall a m r. Monad m => (a -> m Unit) -> Pipe a a m r 182 | chain f = for cat $ \a -> do 183 | lift (f a) 184 | yield a 185 | 186 | -- | Convert `Show`able values to `String`s 187 | show :: forall a m r. Monad m => Show a => Pipe a String m r 188 | show = map Prelude.show 189 | 190 | -- | Evaluate all values flowing downstream to WHNF 191 | -- | XXX: Is this needed in purescript? 192 | seq :: forall a m r. Monad m => Pipe a a m r 193 | seq = for cat $ \a -> yield $ a 194 | 195 | -- | Fold of the elements of a `Producer` 196 | fold 197 | :: forall a b x m 198 | . Monad m 199 | => (x -> a -> x) -> x -> (x -> b) -> Producer a m Unit -> m b 200 | fold step begin done p0 = go p0 begin 201 | where 202 | go p x = case p of 203 | Request v _ -> closed v 204 | Respond a fu -> go (fu unit) $ step x a 205 | M m -> m >>= \p' -> go p' x 206 | Pure _ -> pure (done x) 207 | 208 | -- | Fold of the elements of a `Producer` that preserves the return value 209 | fold' 210 | :: forall a b x m r 211 | . Monad m 212 | => (x -> a -> x) -> x -> (x -> b) -> Producer a m r -> m (Tuple b r) 213 | fold' step begin done p0 = go p0 begin 214 | where 215 | go p x = case p of 216 | Request v _ -> closed v 217 | Respond a fu -> go (fu unit) $ step x a 218 | M m -> m >>= \p' -> go p' x 219 | Pure r -> pure $ Tuple (done x) r 220 | 221 | -- | Monadic fold of the elements of a `Producer` 222 | foldM 223 | :: forall a b x m 224 | . Monad m 225 | => (x -> a -> m x) -> m x -> (x -> m b) -> Producer a m Unit -> m b 226 | foldM step begin done p0 = do 227 | x0 <- begin 228 | go p0 x0 229 | where 230 | go p x = case p of 231 | Request v _ -> closed v 232 | Respond a fu -> do 233 | x' <- step x a 234 | go (fu unit) $ x' 235 | M m -> m >>= \p' -> go p' x 236 | Pure _ -> done x 237 | 238 | -- | Monadic fold of the elements of a `Producer` 239 | foldM' 240 | :: forall a b x m r 241 | . Monad m 242 | => (x -> a -> m x) -> m x -> (x -> m b) -> Producer a m r -> m (Tuple b r) 243 | foldM' step begin done p0 = do 244 | x0 <- begin 245 | go p0 x0 246 | where 247 | go p x = case p of 248 | Request v _ -> closed v 249 | Respond a fu -> do 250 | x' <- step x a 251 | go (fu unit) $ x' 252 | M m -> m >>= \p' -> go p' x 253 | Pure r -> do 254 | b <- done x 255 | pure (Tuple b r) 256 | 257 | -- | all determines whether all the elements of p satisfy the predicate. 258 | all :: forall a m. Monad m => (a -> Boolean) -> Producer a m Unit -> m Boolean 259 | all predicate p = null $ p >-> filter (\a -> not (predicate a)) 260 | 261 | -- | any determines whether any element of p satisfies the predicate. 262 | any :: forall a m. Monad m => (a -> Boolean) -> Producer a m Unit -> m Boolean 263 | any predicate p = liftM1 not $ null (p >-> filter predicate) 264 | 265 | -- | Determines whether all elements are `True` 266 | and :: forall m. Monad m => Producer Boolean m Unit -> m Boolean 267 | and = all identity 268 | 269 | -- | Determines whether any element is `True` 270 | or :: forall m. Monad m => Producer Boolean m Unit -> m Boolean 271 | or = any identity 272 | 273 | -- | elem returns `True` if p has an element equal to a, `False` otherwise 274 | elem :: forall a m. Monad m => Eq a => a -> Producer a m Unit -> m Boolean 275 | elem a = any (a == _) 276 | 277 | -- | notElem returns `False` if p has an element equal to a, `True` otherwise 278 | notElem :: forall a m. Monad m => Eq a => a -> Producer a m Unit -> m Boolean 279 | notElem a = all (a /= _) 280 | 281 | -- | Find the first element of a `Producer` that satisfies the predicate 282 | find :: forall a m. Monad m => (a -> Boolean) -> Producer a m Unit -> m (Maybe a) 283 | find predicate p = head (p >-> filter predicate) 284 | 285 | {-| Find the index of the first element of a `Producer` that satisfies the 286 | predicate 287 | -} 288 | findIndex :: forall a m. Monad m => (a -> Boolean) -> Producer a m Unit -> m (Maybe Int) 289 | findIndex predicate p = head (p >-> findIndices predicate) 290 | 291 | -- | Retrieve the first element from a `Producer` 292 | head :: forall a m. Monad m => Producer a m Unit -> m (Maybe a) 293 | head p = do 294 | x <- next p 295 | pure $ case x of 296 | Left _ -> Nothing 297 | Right (Tuple a _) -> Just a 298 | 299 | -- | Index into a `Producer` 300 | index :: forall a m. Monad m => Int -> Producer a m Unit -> m (Maybe a) 301 | index n p = head (p >-> drop n) 302 | 303 | -- | Retrieve the last element from a `Producer` 304 | last :: forall a m. Monad m => Producer a m Unit -> m (Maybe a) 305 | last p0 = do 306 | x <- next p0 307 | case x of 308 | Left _ -> pure Nothing 309 | Right (Tuple a p') -> go a p' 310 | where 311 | go a p = do 312 | x <- next p 313 | case x of 314 | Left _ -> pure (Just a) 315 | Right (Tuple a' p') -> go a' p' 316 | 317 | -- | Count the number of elements in a `Producer` 318 | length :: forall a m. Monad m => Producer a m Unit -> m Int 319 | length = fold (\n _ -> n + 1) 0 identity 320 | 321 | -- | Find the maximum element of a `Producer` 322 | maximum :: forall a m. Monad m => Ord a => Producer a m Unit -> m (Maybe a) 323 | maximum = fold step Nothing identity 324 | where 325 | step x a = Just $ case x of 326 | Nothing -> a 327 | Just a' -> max a a' 328 | max x y | x >= y = x 329 | | otherwise = y 330 | 331 | -- | Find the minimum element of a `Producer` 332 | minimum :: forall a m. Monad m => Ord a => Producer a m Unit -> m (Maybe a) 333 | minimum = fold step Nothing identity 334 | where 335 | step x a = Just $ case x of 336 | Nothing -> a 337 | Just a' -> min a a' 338 | min x y | x < y = x 339 | | otherwise = y 340 | 341 | -- | Determine if a `Producer` is empty 342 | null :: forall a m. Monad m => Producer a m Unit -> m Boolean 343 | null p = do 344 | x <- next p 345 | pure $ case x of 346 | Left _ -> true 347 | Right _ -> false 348 | 349 | -- | Convert a pure `Producer` into a list 350 | toList :: forall a. Producer a Identity Unit -> List a 351 | toList prod0 = (go prod0) (:) Nil 352 | where 353 | go prod _ nil = 354 | case prod of 355 | Request v _ -> closed v 356 | Respond a fu -> Cons a (go (fu unit) Cons nil) 357 | M m -> go (unwrap m) Cons nil 358 | Pure _ -> nil 359 | 360 | toListM :: forall a m. Monad m => Producer a m Unit -> m (List a) 361 | toListM = fold step begin done 362 | where 363 | step x a = x <<< (a : _) 364 | begin = identity 365 | done x = x Nil 366 | --------------------------------------------------------------------------------