{"id":16014642,"url":"https://github.com/functionalland/functional-io","last_synced_at":"2026-03-06T19:07:47.677Z","repository":{"id":62421743,"uuid":"294157688","full_name":"functionalland/functional-io","owner":"functionalland","description":"IO methods as valid Task monads perfect to write great point-free software in JavaScript that is compatible with most modern browsers and Deno.","archived":false,"fork":false,"pushed_at":"2021-01-03T16:33:54.000Z","size":150,"stargazers_count":11,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-11-09T23:38:10.267Z","etag":null,"topics":["algebraic-data-types","deno","denoland","filesystem","functional","functional-programming","functor","monad","task-monad"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/functionalland.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-09-09T15:43:37.000Z","updated_at":"2022-04-08T12:06:51.000Z","dependencies_parsed_at":"2022-11-01T17:31:48.115Z","dependency_job_id":null,"html_url":"https://github.com/functionalland/functional-io","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/functionalland/functional-io","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/functionalland%2Ffunctional-io","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/functionalland%2Ffunctional-io/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/functionalland%2Ffunctional-io/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/functionalland%2Ffunctional-io/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/functionalland","download_url":"https://codeload.github.com/functionalland/functional-io/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/functionalland%2Ffunctional-io/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30192445,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T18:54:55.862Z","status":"ssl_error","status_checked_at":"2026-03-06T18:53:04.013Z","response_time":250,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algebraic-data-types","deno","denoland","filesystem","functional","functional-programming","functor","monad","task-monad"],"created_at":"2024-10-08T15:04:29.730Z","updated_at":"2026-03-06T19:07:47.658Z","avatar_url":"https://github.com/functionalland.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"./.github/fl-logo.svg\" alt=\"Functional IO\" width=\"450\" /\u003e\n\nIO methods as valid Task monads perfect to write great point-free software in JavaScript that is compatible with most modern browsers and Deno.\n\n[![deno land](http://img.shields.io/badge/available%20on-deno.land/x-lightgrey.svg?logo=deno\u0026labelColor=black)](https://deno.land/x/functional_io@v1.1.0)\n[![deno version](https://img.shields.io/badge/deno-^1.6.1-lightgrey?logo=deno)](https://github.com/denoland/deno)\n[![GitHub release](https://img.shields.io/github/v/release/sebastienfilion/functional-io)](https://github.com/sebastienfilion/functional-io/releases)\n[![GitHub licence](https://img.shields.io/github/license/sebastienfilion/functional-io)](https://github.com/sebastienfilion/functional-io/blob/v1.1.0/LICENSE)\n[![Discord Chat](https://img.shields.io/discord/790708610023555093.svg)](https://discord.gg/)\n\n  * [Buffer](#buffer)\n  * [Directory](#directory)\n  * [File](#file)\n  * [File System Collection](#file-system-collection)\n  * [Request](#request)\n  * [Resource](#resource)\n  * [Response](#response)\n  * [URL](#url)\n  * [Browser safe](#browser-safe)\n  * [File System](#file-system)\n  * [Utilities](#utilities)\n  * [TypeScript](#typescript)\n\n# Usage\n\nThis example uses the [Ramda library](https://ramdajs.com) - for simplification - but you should be able to use any\nlibrary that implements the [Fantasy-land specifications](https://github.com/fantasyland/fantasy-land).\n\n```js\nimport { __, ap, chain, compose, lift, map, match, path, prop, useWith } from \"https://deno.land/x/ramda@v0.27.2/mod.ts\";\nimport Task from \"https://deno.land/x/functional@v1.3.3/library/Task.js\";\nimport { safeExtract } from \"https://deno.land/x/functional@v1.3.3/library/utilities.js\";\nimport Request from \"https://deno.land/x/functional_io@v1.1.0/library/Request.js\";\nimport { factorizeFile } from \"https://deno.land/x/functional_io@v1.1.0/library/File.js\";\nimport { fetch } from \"https://deno.land/x/functional_io@v1.1.0/library/browser_safe.js\";\nimport { writeFile } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\n\nconst fetchBacon = compose(\n  chain(writeFile({})),\n  ap(\n    useWith(\n      lift(factorizeFile(__, __, 0)),\n      [\n        compose(\n          Task.of,\n          name =\u003e `${Deno.cwd()}/${name}.html`,\n          prop(1),\n          match(/\\?type=([A-Za-z\\-]+)/),\n          path([ \"headers\", \"url\" ])\n        ),\n        map(prop(\"raw\"))\n      ]\n    ),\n    fetch\n  )\n);\n\nconst container = fetchBacon(\n  Request.get(\"https://baconipsum.com/api/?type=all-meat\u0026paras=3\u0026start-with-lorem=1\u0026format=html\")\n);\n\n// Calling `fetchBacon` results in an instance of `Task` keeping the function pure.\nassert(Task.is(container));\n\nconst file = safeExtract(\"Failed to write file.\", await container.run());\n\nassert(File.is(file));\n```\n\n### Using the bundle\n\nAs a convenience, when using Functional IO in the browser, you can use the **unminified** bundled copy (18KB gzipped).\n\n```js\nimport { Task, safeExtract } from \"https://deno.land/x/functional@v1.3.3/functional.js\";\nimport { Request, Response, fetch } from \"https://deno.land/x/functional_io@v1.1.0/functional-io.js\";\n\nconst container = fetch(\n  Request.get(\"https://baconipsum.com/api/?type=all-meat\u0026paras=3\u0026start-with-lorem=1\u0026format=html\")\n);\n\nassert(Task.is(container));\n\nconst response = safeExtract(\"Failed to fetch resource.\", await container.run());\n\nassert(Response.is(response));\n```\n\n---\n\n## Buffer\n\nThe `Buffer` is the most basic type; it only has one attribute which is a typed array named \"raw\".\nAny type that share the raw attribute is composable with `Buffer` (and each other) and interoperable.\n\nThe `Buffer` type implements the following algebras:\n- [x] Group\n- [x] Comonad\n- [x] Monad\n\n### Example\n\n```js\nimport Buffer from \"https://deno.land/x/functional_io@v1.1.0/library/Buffer.js\";\n\nconst buffer = Buffer.fromString(\"hoge\").concat(Buffer.fromString(\"fuga\"));\n\nassert(Buffer.is(buffer));\n```\n\n---\n\n## Directory\n\nThe `Directory` type represents a directory on the file system. It is the only type with the same shape as `URL`.\nIt has only one attributes: the path of the directory.\nA `Directory` is interoperable with a `URL` or a `File`.\nIt also has interoperability with a `File` through the `FileSystemCollection` type.\n\nThe `Directory` type implements the following algebras:\n- [x] Ord\n- [x] Comonad\n- [x] Monad\n\n### Example\n\n```js\nassert(Directory(`${Deno.cwd()}/hoge`).lte(Directory(`${Deno.cwd()}/piyo`)));\n```\n\n---\n\n## File\n\nThe `File` type extends the `Resource` type. It represents a file with a path.\nIt has three attributes: the first is the path of the file, the second is a typed array named \"raw\" and the last\nis the Resource ID (`rid`).\nA `File` is composable and interoperable with a `Resource` or a `Buffer` -- It also has some interoperability with a\n`Location` through the `FileSystemCollection`.\n\nThe `File` type implements the following algebras:\n- [x] Group\n- [x] Bifunctor\n- [x] Comonad\n- [x] Monad\n\n### Example\n\n```js\nconst file = File(`${Deno.cwd()}/hoge`, new Uint8Array([ 65, 66, 67, 68, 69 ]), 3)\n  .concat(File(`${Deno.cwd()}/piyo`, new Uint8Array([ 70, 71, 72, 73, 74 ]), 3));\n\nassert(File.is(file));\n```\n\n---\n\n## File System Collection\n\nThe `FileSystemCollection` is represents a collection of `Location`, namely of `Directory` and `File`. This of it\nas an Array for those types.\n\nThe `FileSystemCollection` type implements the following algebras:\n- [x] Group\n- [x] Comonad\n- [x] Monad\n- [x] Traversable\n\n### Example\n\n```js\nconst containerA = Maybe.Just(42).map(x =\u003e x + 2);\nconst containerB = Maybe.Nothing.map(x =\u003e x + 2);\n\nassert(Maybe.Just.is(containerA));\nassert(containerA.extract() === 44);\nassert(Maybe.Nothing.is(containerB));\n```\n\n---\n\nFile Group algebra law \"Left identity\" and \"Right identity\" is not respected because the rid can't be modified\nwithout using bimap.\n\n---\n\n## Request\n\nThe `Request` represent a HTTP request.\nIt has two attributes: the first is an object for the response \"header\" and the second is a typed array named \"raw\".\nThe `Request` type is mostly interoperable with `Resource`, `File` and `Response`.\n\nThe `Resource` type implements the following algebras:\n- [x] Group\n- [x] Bifunctor\n- [x] Monad\n\n### Example\n\n```js\nconst request = Request({}, new Uint8Array([ 65, 66, 67, 68, 69 ]))\n  .concat(Resource(new Uint8Array([ 70, 71, 72, 73, 74 ]), 3));\n\nassert(Request.is(request));\n```\n\n#### Utilities\n\nThe `Request` namespace comes with 4 methods for convenience to create an instance of `Request` with a common verb.\nThe methods are curried when necessary. `Object → Unint8Array → Response`\n\n```js\nconst container = compose(\n  lift(Request.post({ [\"Content-Type\"]: \"application/json\" })),\n  readFile\n)(File.fromPath(`${Deno.cwd()}/hoge`));\n\nassert((await container.run()).extract().headers.method === \"POST\");\n```\n\n| Method name            | Has 2 arguments |\n|------------------------|-----------------|\n| `delete` | `DELETE`    | false           |\n| `get` | `GET`          | false           |\n| `post` | `POST`        | true            |\n| `put` | `PUT`          | true            |\n\n✢ *The capitalized version of the methods were added because `delete` is a TypeScript reserved word.*\n\n---\n\nRequest Semigroup algebra law \"Left identity\" is not respected because the headers can't be modified without using\nbimap.\n\nRequest Monoid algebra law \"Left identity\" is not respected because the headers can't be modified without using\nbimap.\n\nRequest Group algebra law \"Left identity\" and \"Right identity\" is not respected because the headers can't be\nmodified without using bimap.\n\nRequest Modnad algebra law \"Right identity\" is not respected because the headers can't be modified without using\nbimap.\n\nRequest Applicative algebra law \"Interchange\" is not respected because the headers can't be modified without using\nbimap.\n\n---\n\n## Resource\n\nThe `Resource` type extends the `Buffer` type. It represents a system resource with a handle, eg: STDOUT, STDIN or a\nfile. It has two attributes: the first is a typed array named \"raw\" and the second is the Resource ID (`rid`).\nAny type that share the `Resource` attributes is composable and interoperable.\n\nThe `Resource` type implements the following algebras:\n- [x] Group\n- [x] Bifunctor\n- [x] Comonad\n- [x] Monad\n\n### Example\n\n```js\nconst resource = Resource(new Uint8Array([ 65, 66, 67, 68, 69 ]), 3)\n  .concat(Resource(new Uint8Array([ 70, 71, 72, 73, 74 ]), 3));\n\nassert(Resource.is(resource));\n```\n\n---\n\nResource Monoid algebra law \"Left identity\" is not respected because the rid can't be modified without using\nbimap.\n\nResource Group algebra law \"Left identity\" and \"Right identity\" is not respected because the rid can't be modified\nwithout using bimap.\n\nResource Modnad algebra law \"Right identity\" is not respected because the rid can't be modified without using\nbimap.\n\nResource Applicative algebra law \"Interchange\" is not respected because the rid can't be modified without using\nbimap.\n\n---\n\n## Response\n\nThe `Response` represent a HTTP response.\nIt has two attributes: the first is an object for the response \"header\" and the second is a typed array named \"raw\".\nThe `Response` type is mostly interoperable with `Resource`, `File` and `Request`.\n\nThe `Resource` type implements the following algebras:\n- [x] Alternative\n- [x] Group\n- [x] Bifunctor\n- [x] Monad\n\n### Example\n\n```js\nconst response = Response.Success({}, new Uint8Array([ 65, 66, 67, 68, 69 ]))\n  .concat(Resource(new Uint8Array([ 70, 71, 72, 73, 74 ]), 3));\n\nassert(Response.is(response));\n```\n\n#### Utilities\n\nThe `Response` namespace comes with 38 methods for convenience to create an instance of `Response` with a common\nstatus.\nThe methods are curried: `Object → Uint8Array → Response`\n\n```js\nconst container = compose(\n  lift(Response.OK({ [\"Content-Type\"]: \"application/json\" })),\n  readFile\n)(File.fromPath(`${Deno.cwd()}/hoge`));\n\nassert((await container.run()).extract().headers.status === 200);\n```\n\n| Method name           | Status |\n|-----------------------|--------|\n| `OK`                  | 200    |\n| `Created`             | 201    |\n| `Accepted`            | 202    |\n| `NoContent`           | 204    |\n| `MultipleChoice`      | 300    |\n| `MovePermanently`     | 301    |\n| `Found`               | 302    |\n| `NotModified`         | 304    |\n| `TemporaryRedirect`   | 307    |\n| `PermanentRedirect`   | 308    |\n| `BadRequest`          | 400    |\n| `Unauthorized`        | 401    |\n| `Forbidden`           | 403    |\n| `NotFound`            | 404    |\n| `MethodNotAllowed`    | 405    |\n| `NotAcceptable`       | 406    |\n| `RequestTimeout`      | 408    |\n| `Conflict`            | 409    |\n| `Gone`                | 410    |\n| `ImATeapot`           | 418    |\n| `InternalServerError` | 500    |\n| `NotImplemented`      | 501    |\n| `BadGateway`          | 502    |\n| `ServiceUnavailable`  | 503    |\n| `GatewayTimeout`      | 504    |\n| `PermissionDenied`    | 550    |\n\n---\n\nResponse Semigroup algebra law \"Left identity\" is not respected because the headers can't be modified without using\nbimap.\n\nResponse Monoid algebra law \"Left identity\" is not respected because the headers can't be modified without using\nbimap.\n\nResponse Group algebra law \"Left identity\" and \"Right identity\" is not respected because the headers can't be\nmodified without using bimap.\n\nResponse Modnad algebra law \"Right identity\" is not respected because the headers can't be modified without using\nbimap.\n\nResponse Applicative algebra law \"Interchange\" is not respected because the headers can't be modified without using\nbimap.\n\n---\n\n## URL\n\nThe `URL` type represents an URL; either of a location on the file system or on a remote server.\nIt has only one attributes: the path of the URL.\nA `URL` is interoperable with a `File` or a `Directory`.\nIt also has interoperability with a `File` or a `Directory` through the `FileSystemCollection` type.\n\nThe `URL` type implements the following algebras:\n- [x] Ord\n- [x] Comonad\n- [x] Monad\n\n### Example\n\n```js\nassert(URL(`${Deno.cwd()}/hoge`).lte(URL(`${Deno.cwd()}/piyo`)));\n```\n\n---\n\n## Browser safe\n\n### `pureFetch`\n`Request → Task e Response`\n\nFetches a resource on a local/remote server.\n\n```js\nimport { fetch } from \"https://deno.land/x/functional_io@v1.1.0/library/browser-safe.js\";\n\nconst containerA = fetch(Request.GET(\"http://localhost:8000\"));\n\nassert(Task.is(containerA));\n\nconst containerB = await container.run().extract();\n\nassert(Response.Success.is(containerB));\n```\n\n---\n\n## File System\n\n**⚠️ Note** `Deno.cwd` is used in the following example; if you use `Deno.cwd` to compose your paths, your functions\nare no longer pure.\n\n### `chdir` [📕](https://doc.deno.land/builtin/stable#Deno.chdir)\n`Directory → Task e Directory`\n\nChange the current working directory to the specified path.\n\n```js\nimport { chdir } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\n\nconst container = chdir(Directory(\"..\"));\n\nassert(Task.is(container));\n```\n\n### `chmod` [📕](https://doc.deno.land/builtin/stable#Deno.chmod)\n`Number → File → Task e File`\n\nChanges the permission of a specific file/directory of specified path. Ignores the process's umask.\n\n```js\nimport { chmod } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\n\nconst container = chmod(0o000, File.fromPath(`${Deno.cwd()}/hoge`));\n\nassert(Task.is(container));\n```\n\n### `chown` [📕](https://doc.deno.land/builtin/stable#Deno.chown)\n`Number → Number → File → Task e File`\n\nChange owner of a regular file or directory. This functionality is not available on Windows.\n\n```js\nimport { chown } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\n\nconst container = chown(null, null, File.fromPath(`${Deno.cwd()}/hoge`));\n\nassert(Task.is(container));\n```\n\n### `close` [📕](https://doc.deno.land/builtin/stable#Deno.close)\n`Resource → Task e Resource`\n\nClose the given resource which has been previously opened, such as via opening or creating a file.\nClosing a file when you are finished with it is important to avoid leaking resources.\n\n```js\nimport { close } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\n\nconst container = close(File(`${Deno.cwd()}/hoge`, new Uint8Array([]), 3));\n\nassert(Task.is(container));\n```\n\n### `copy` [📕](https://doc.deno.land/builtin/stable#Deno.copy)\n`Object → Buffer a → Buffer b → Task e Buffer b`\n\nCopies from a source to a destination until either EOF (null) is read from the source, or an error occurs.\n\n```js\nimport { copy } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\n\nconst container = copy({}, Buffer(new Uint8Array([ 65, 66, 67, 68, 69 ])), Buffer(new Uint8Array([])));\n\nassert(Task.is(container));\n```\n\n### `copyFile` [📕](https://doc.deno.land/builtin/stable#Deno.copyFile)\n`File a → File b → Task e File b`\n\nCopies the contents and permissions of one file to another specified file, by default creating a new file if needed,\nelse overwriting. Fails if target path is a directory or is unwritable.\n\n```js\nimport { copyFile } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\n\nconst container = copyFile(File.fromPath(`${Deno.cwd()}/hoge`), File.fromPath(`${Deno.cwd()}/piyo`));\n\nassert(Task.is(container));\n```\n\n### `create` [📕](https://doc.deno.land/builtin/stable#Deno.create)\n`File → Task e File`\n\nCreates a file if none exists or truncates an existing file.\n\n```js\nimport { create } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\n\nconst container = create(File.fromPath(`${Deno.cwd()}/hoge`));\n\nassert(Task.is(container));\n```\n\n### `cwd` [📕](https://doc.deno.land/builtin/stable#Deno.cwd)\n\nReturn a Directory representation of the current working directory.\n`() → Task e Directory`\n\n```js\nimport { cwd } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\n\nconst container = cwd();\n\nassert(Task.is(container));\n```\n\n### `ensureDir` [📕](https://deno.land/std@0.79.0/fs#ensuredir)\n`Directory → Task e Directory`\n\nEnsures that the directory exists. If the directory structure does not exist, it is created. Like `mkdir -p`.\n\n```js\nimport { ensureDir } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\n\nconst container = emptyDir(Directory(`${Deno.cwd()}/hoge`));\n\nassert(Task.is(container));\n```\n\n### `exists` [📕](https://deno.land/std@0.79.0/fs#exists)\n`URL → Task e|null URL\n\nTest whether the given path exists by checking with the file system.\nIf the file or directory doesn't exist, it will resolve to `Either.Left(null)`.\n\n```js\nimport { exists } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\n\nconst container = exists(Directory(`${Deno.cwd()}/hoge`));\n\nassert(Task.is(container));\n```\n\n### `mkdir` [📕](https://deno.land/std@0.79.0/fs#mkdir)\n`Object → Directory → Task e Directory`\n\nCreates a new directory with the specified path.\n\n```js\nimport { mkdir } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\n\nconst container = mkdir({}, Directory(`${Deno.cwd()}/hoge`));\n\nassert(Task.is(container));\n```\n\n### `move` [📕](https://deno.land/std@0.79.0/fs#move)\n`Object → String → URL → Task e URL`\n\nMoves a file or directory.\n\n```js\nimport { move } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\n\nconst container = move({}, `${Deno.cwd()}/piyo`, Directory(`${Deno.cwd()}/hoge`));\n\nassert(Task.is(container));\n```\n\n### `open` [📕](https://doc.deno.land/builtin/stable#Deno.open)\n`Object → File → Task e File`\n\nOpen a file and resolve to an instance of File. The file does not need to previously exist if using the create or\ncreateNew open options. It is the callers responsibility to close the file when finished with it.\n\n```js\nimport { open } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\n\nconst container = open({ read: true, write: true }, File.fromPath(`${Deno.cwd()}/hoge`));\n\nassert(Task.is(container));\n```\n\n### `read` [📕](https://doc.deno.land/builtin/stable#Deno.read)\n`Resource Task e Resource`\n\nRead from a Resource given it has a non-zero raw buffer.\n\n```js\nimport { read } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\n\nconst container = read(File(`${Deno.cwd()}/hoge`, new Uint8Array(5), 3));\n\nassert(Task.is(container));\n```\n\n### `readLine`\n`Resource → Task e Resource`\n\nRead from a Resource to the CLRF.\n\n```js\nimport { readLine } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\n\nconst container = readLine(File(`${Deno.cwd()}/hoge`, new Uint8Array([]), 3));\n\nassert(Task.is(container));\n```\n\n### `readNBytes`\n`Number → Resource → Task e Resource`\n\nRead N bytes from a Resource.\n\n```js\nimport { readNBytes } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\n\nconst container = readNBytes(5, File(`${Deno.cwd()}/hoge`, new Uint8Array([]), 3));\n\nassert(Task.is(container));\n```\n\n### `readOneByte`\n`Resource → Task e Resource`\n\nRead 1 byte from a Resource.\n\n```js\nimport { readOneByte } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\n\nconst container = readOneByte(File(`${Deno.cwd()}/hoge`, new Uint8Array([]), 3));\n\nassert(Task.is(container));\n```\n\n### `readAll` [📕](https://doc.deno.land/builtin/stable#Deno.readAll)\n`Resource → Task e Resource`\n\nRead from a Resource.\n\n```js\nimport { readAll } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\n\nconst container = readAll(File(`${Deno.cwd()}/hoge`, new Uint8Array([]), 3));\n\nassert(Task.is(container));\n```\n\n### `readFile` [📕](https://doc.deno.land/builtin/stable#Deno.readFile)\n`File → Task e File`\n\nRead from a File.\n\n```js\nimport { readFile } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\n\nconst container = readFile(File(`${Deno.cwd()}/hoge`, new Uint8Array([]), 3));\n\nassert(Task.is(container));\n```\n\n### `remove` [📕](https://doc.deno.land/builtin/stable#Deno.remove)\n`Object → URL → Task e URL`\n\nRemoves the named file or directory.\n\n```js\nimport { remove } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\n\nconst container = remove({ recursive: true }, Directory.fromPath(`${Deno.cwd()}/hoge`));\n\nassert(Task.is(container));\n```\n\n### `rename` [📕](https://doc.deno.land/builtin/stable#Deno.rename)\n`String → URL → Task e URL`\n\nRenames a file or directory.\n\n```js\nimport { rename } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\n\nconst container = rename(`${Deno.cwd()}/piyo`, Directory(`${Deno.cwd()}/hoge`));\n\nassert(Task.is(container));\n```\n\n### `write` [📕](https://doc.deno.land/builtin/stable#Deno.write)\n`Resource → Task e Resource`\n\nWrite to a Resource given it has a non-zero raw buffer.\n\n```js\nimport { write } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\n\nconst container = write(File(`${Deno.cwd()}/hoge`, new Uint8Array([ 65, 66, 67, 68, 69 ]), 3));\n\nassert(Task.is(container));\n```\n\n### `writeAll` [📕](https://doc.deno.land/builtin/stable#Deno.writeAll)\n`Buffer → Task e Resource`\n\nWrite all to a Resource from a Buffer.\n\n```js\nimport { writeAll } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\n\nconst container = writeAll(\n  Buffer(new Uint8Array([ 65, 66, 67, 68, 69 ])),\n  File(`${Deno.cwd()}/hoge`, new Uint8Array([]), 3)\n);\n\nassert(Task.is(container));\n```\n\n### `writeFile` [📕](https://doc.deno.land/builtin/stable#Deno.writeFile)\n`Object → File → Task e File`\n\nWrite a File to the file system.\n\n```js\nimport { writeFile } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\n\nconst container = writeFile({}, File(`${Deno.cwd()}/hoge`, new Uint8Array([]), 3));\n\nassert(Task.is(container));\n```\n\n---\n\n## Utilities\n\n### `findCLRFIndex`\n`Uint8Array → Number`\n\nThis function takes a `Uint8Array` and, returns the index of the last character of the first CLRF sequence\nencountered.\n\n```js\nimport { findCLRFIndex } from \"https://deno.land/x/functional_io@v1.1.0/library/utilities.js\";\n\nassertEquals(findCLRFIndex(new Uint8Array([ 104, 111, 103, 101, 13, 10 ])), 6);\n```\n\n### `discardFirstLine`\n`Uint8Array → Uint8Array`\n\nThis function takes a `Uint8Array` and, returns the typed array minus the first line separated by CLRF.\n\n```js\nimport { discardFirstLine } from \"https://deno.land/x/functional_io@v1.1.0/library/utilities.js\";\n\nassertEquals(\n  discardFirstLine(new Uint8Array([ 104, 111, 103, 101, 13, 10, 104, 111, 103, 101, 13, 10 ])),\n  new Uint8Array([ 104, 111, 103, 101, 13, 10 ])\n);\n```\n\n### `discardNCharacter`\n`Number → Uint8Array → Uint8Array`\n\nThis function takes a Number, a `Uint8Array` and, returns the typed array minus the specified amount of character\nstarting from the left side.\n\n```js\nimport { discardNCharacter } from \"https://deno.land/x/functional_io@v1.1.0/library/utilities.js\";\n\nassertEquals(\n  discardNCharacter(1, new Uint8Array([ 104, 111, 103, 101, 13, 10 ])),\n  new Uint8Array([ 111, 103, 101, 13, 10 ])\n);\n```\n\n### `getFirstLine`\n`Uint8Array → Uint8Array`\n\nThis function takes a `Uint8Array` and, returns the first line separated by a CLRF inclusively.\n\n```js\nimport { getFirstLine } from \"https://deno.land/x/functional_io@v1.1.0/library/utilities.js\";\n\nassertEquals(\n  getFirstLine(new Uint8Array([ 104, 111, 103, 101, 13, 10, 104, 111, 103, 101, 13, 10 ])),\n  new Uint8Array([ 104, 111, 103, 101, 13, 10 ])\n);\n```\n\n### `joinCLRF`\n`Uint8Array[] → Uint8Array`\n\nThis function takes a list of `Uint8Array` and, returns a `Uint8Array` of the list joined with CLRF sequence; the\nfunction is analogous to `Array#join`.\n\n```js\nimport { joinCLRF } from \"https://deno.land/x/functional_io@v1.1.0/library/utilities.js\";\n\nassertEquals(\n  joinCLRF(\n    [\n      new Uint8Array([ 104, 111, 103, 101 ]),\n      new Uint8Array([ 104, 111, 103, 101 ])\n    ]\n  ),\n  new Uint8Array([ 104, 111, 103, 101, 13, 10, 104, 111, 103, 101, 13, 10 ])\n);\n```\n\n### `splitCLRF`\n`Uint8Array → Uint8Array[]`\n\nThis function takes a `Uint8Array` and, returns a list of `Uint8Array` of subarray split at the CLRF sequence; the\nfunction is analogous to `String#split`.\n\n```js\nimport { splitCLRF } from \"https://deno.land/x/functional_io@v1.1.0/library/utilities.js\";\n\nassertEquals(\n  splitCLRF(new Uint8Array([ 104, 111, 103, 101, 13, 10, 104, 111, 103, 101, 13, 10 ])),\n  [\n    new Uint8Array([ 104, 111, 103, 101, 13, 10 ]),\n    new Uint8Array([ 104, 111, 103, 101, 13, 10 ])\n  ]\n);\n```\n\n### `trimCRLF`\n`Uint8Array → Uint8Array`\n\nThis function takes a `Uint8Array` and, returns a typed array minus CRLF at the beginning and at the end;\nthe function is analogous to `String#trim`.\n\n```js\nimport { trimCRLF } from \"https://deno.land/x/functional_io@v1.1.0/library/utilities.js\";\n\nassertEquals(\n  trimCRLF(new Uint8Array([ 104, 111, 103, 101, 13, 10 ])),\n  new Uint8Array([ 104, 111, 103, 101 ])\n);\n```\n\n### `factorizeUint8Array`\n`Number|Array|Uint8Array → Uint8Array\n\nThis function factorize a Uint8Array given an argument.\n\n---\n\n## TypeScript\n\nYou can import any types.\n\n```ts\nimport {\n  Buffer,\n  Directory,\n  File,\n  Request,\n  Resource,\n  Response,\n  URL\n} from \"https://deno.land/x/functional_io@v1.1.0/mod.ts\";\n```\n\nOr, you can import individual sub-module with the appropriate TypeScript hint in Deno.\n\n```ts\n// @deno-types=\"https://deno.land/x/functional_io@v1.1.0/library/Request.d.ts\"\nimport Request from \"https://deno.land/x/functional_io@v1.1.0/library/Request.js\";\n```\n \n---\n\n## Contributing\n\nWe appreciate your help! Please, [read the guidelines](./CONTRIBUTING.md).\n\n## License\n\nCopyright © 2020 - Sebastien Filion\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated \ndocumentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the \nrights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit \npersons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the \nSoftware.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE \nWARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR \nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR \nOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffunctionalland%2Ffunctional-io","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffunctionalland%2Ffunctional-io","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffunctionalland%2Ffunctional-io/lists"}