{"id":32258440,"url":"https://github.com/jamieyung/purescript-selection-foldable","last_synced_at":"2026-02-22T15:02:05.841Z","repository":{"id":58225584,"uuid":"147778762","full_name":"jamieyung/purescript-selection-foldable","owner":"jamieyung","description":"A Foldable structure of items where zero or one of the items is selected.","archived":false,"fork":false,"pushed_at":"2018-09-10T17:17:32.000Z","size":28,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-01-23T20:35:36.341Z","etag":null,"topics":["datatype","purescript"],"latest_commit_sha":null,"homepage":"","language":"PureScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jamieyung.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-09-07T06:10:39.000Z","updated_at":"2019-05-30T15:22:13.000Z","dependencies_parsed_at":"2022-08-31T04:10:16.576Z","dependency_job_id":null,"html_url":"https://github.com/jamieyung/purescript-selection-foldable","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/jamieyung/purescript-selection-foldable","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamieyung%2Fpurescript-selection-foldable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamieyung%2Fpurescript-selection-foldable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamieyung%2Fpurescript-selection-foldable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamieyung%2Fpurescript-selection-foldable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jamieyung","download_url":"https://codeload.github.com/jamieyung/purescript-selection-foldable/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamieyung%2Fpurescript-selection-foldable/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29716528,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-22T13:30:57.152Z","status":"ssl_error","status_checked_at":"2026-02-22T13:30:28.561Z","response_time":110,"last_error":"SSL_read: 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":["datatype","purescript"],"created_at":"2025-10-22T19:48:58.973Z","updated_at":"2026-02-22T15:02:05.816Z","avatar_url":"https://github.com/jamieyung.png","language":"PureScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SelectionFoldable\n\nThe `SelectionFoldable` type represents a Foldable structure (eg. Array, List)\nof items where zero or one of the items is selected.\n\nAlso provided is the\n`SelectionFoldableWithData` type, which also keeps some user-provided data along\nwith the selected item (the `SelectionFoldable` type is actually just a type\nalias for a `SelectionFoldableWithData` where there is no data).\n\nInspired by the excellent Elm\n[list-selection](https://github.com/NoRedInk/list-selection) package written by\n[NoRedInk](https://github.com/NoRedInk).\n\n## Usage examples\n\n**Note 1**: All of the code examples in this README assume the following\nimports (common imports like Prelude are implicit):\n\n```purescript\nimport Data.SelectionFoldable as SF\nimport Data.SelectionFoldableWithData as SFWD\n```\n\n**Note 2**: These examples use the `#` operator, which is left-to-right function\napplication:\n\n```purescript\n1 # (\\n -\u003e n + 2) -- Add 2\n-- 3\n\n[1,2,3] # map (\\n -\u003e n + 1) -- Add one to each number\n-- [2,3,4]\n\n[1,2,3]\n    # map (\\n -\u003e n + 1) -- 1. Add one to each number, then\n    # map (\\n -\u003e n \u003c 4) -- 2. Map the numbers to bools\n-- [true,true,false]\n```\n\n#### Creating:\n\nAny Foldable structure can be plugged in. Items and associated data can be of\nany type:\n\n```purescript\n-- Using an Array:\nx1 :: SF.SelectionFoldable Array Int\nx1 = SF.fromFoldable [1,2,3]\n\n-- Using a List:\nx2 :: SF.SelectionFoldable List String\nx2 = SF.fromFoldable (Cons \"a\" Nil)\n\n-- This seems a bit silly, but it's possible!\nx3 :: SF.SelectionFoldable Maybe Boolean\nx3 = SF.fromFoldable (Just true)\n\n-- Here `Bool` is the type of user-provided data associated with selected items.\n-- The compiler will often require you to provide this type annotation.\nx4 :: SFWD.SelectionFoldableWithData Array Bool Int\nx4 = SFWD.fromFoldable [1,2,3]\n\n-- Any types will work!\ndata Foo = A | B\nx5 :: SFWD.SelectionFoldableWithData Array Foo Foo\nx5 = SFWD.fromFoldable [A,B]\n```\n\n#### Selecting by equality:\n\nUsing `select` or `selectIndex` will select items by equality to the provided\nitem (this obviously requires an `Eq` instance for the item type):\n\n```purescript\nx1 :: SF.SelectionFoldable Array Int\nx1 = SF.fromFoldable [1,3,9] # SF.select 3 -- Selects the second element\n-- SF.selected x1 = Just 3 :: Maybe Int\n\nx2 :: SF.SelectionFoldable Array Int\nx2 = SF.fromFoldable [1,3,9] # SF.select 2 -- Selects nothing\n-- SF.selected x2 = Nothing :: Maybe Int\n\nx3 :: SF.SelectionFoldable Array String\nx3 = SF.fromFoldable [\"a\",\"b\",\"c\"] # SF.selectIndex 0 -- Selects the 'a'\n-- SF.selected x3 = Just \"a\" :: Maybe String\n\nx4 :: SF.SelectionFoldable Array Int\nx4 = SF.fromFoldable [1,3,9] # SF.select 10 -- Selects nothing (out of bounds)\n-- SF.selected x4 = Nothing :: Maybe Int\n\nx4 :: SF.SelectionFoldableWithData Array String Int\nx4 = SF.fromFoldable [1, 0, 2]\n    # SF.select \"woo!\" 2 -- Selects the 2, and stores the string \"woo!\" with it\n-- SF.selected x4 = Just (Tuple \"woo!\" 2) :: Maybe (Tuple String Int)\n```\n\n#### Selecting with a function:\n\nUsing `selectWith` or `selectWithIndex` will select items using the provided\nfunction:\n\n```purescript\nx1 :: SF.SelectionFoldable Array Int\nx1 = SF.fromFoldable [1,3,9]\n    # SF.selectWith (_ \u003e 1) -- Selects the second element\n-- SF.selected x1 = Just 3 :: Maybe Int\n\nx2 :: SF.SelectionFoldable Array Int\nx2 = SF.fromFoldable [1,3,9]\n    # SF.selectWith (_ \u003c 1) -- Selects nothing\n-- SF.selected x2 = Nothing :: Maybe Int\n\nx3 :: SF.SelectionFoldable Array Int\nx3 = SF.fromFoldable [1, 0, 2]\n    # SF.selectWithIndex (\\i s -\u003e i == s) -- Selects the 2\n-- SF.selected x3 = Just 2 :: Maybe Int\n```\n\nThis does not require an `Eq` instance for the item type to work:\n\n```purescript\ndata Foo = A | B -- no Eq instance for Foo\n\nx1 :: SF.SelectionFoldable Array String\nx1 = SF.fromFoldable [A, B]\n    # SF.selectWith (\\x -\u003e case x of\n        A -\u003e false\n        B -\u003e true\n    ) -- selects the B\n\nx2 :: Maybe Int\nx2 = SF.selected x1\n    # map (\\x -\u003e case x of\n        A -\u003e 1\n        B -\u003e 2\n    ) -- Just 2 :: Maybe Int\n```\n\n#### Mapping:\n\nThe selected item (if it exists) gets mapped as well as the items in the\nstructure:\n\n```purescript\nx1 :: SF.SelectionFoldable Array Int\nx1 = SF.fromFoldable [1,3,9]\n    # SF.selectIndex 0 -- Selects the '1'\n    # map (\\n -\u003e n + 1)\n-- SF.toFoldable x1 = [2,4,10] :: Array Int\n-- SF.selected x1 = Just 2 :: Maybe Int\n\nx2 :: SF.SelectionFoldable Array Bool\nx2 = SF.fromFoldable [1,3,9]\n    # SF.select 10 -- Selects nothing (out of bounds)\n    # map (\\n -\u003e n + 1)\n-- SF.toFoldable x1 = [2,4,10] :: Array Int\n-- SF.selected x1 = Nothing :: Maybe Int\n```\n\n#### Folding:\n\n```purescript\nSF.fromFoldable [1,2,3]\n    # SF.select 1\n    # SF.foldrSelected (\\isSelected x z -\u003e\n        if isSelected then\n            (show x \u003c\u003e \"!\") : z\n        else\n            (show x) : z\n    ) []\n-- [\"1!\",\"2\",\"3\"] :: Array String\n\nSFWD.fromFoldable [1,2,3]\n    # SFWD.select \"!\" 1\n    # SFWD.foldrSelected\n        { sel: \\(Tuple s x) z -\u003e (show x \u003c\u003e s) : z\n        , rest: \\x z -\u003e (show x) : z\n        } []\n-- [\"1!\",\"2\",\"3\"] :: Array String\n```\n\nSee `test/Test/Main.purs` for further examples.\n\n## Invariants\n\n#### It's impossible to select an item that isn't found in the Foldable structure.\n\nThis guarantee comes out of the fact that the data\nconstructor is private, and the exposed functions maintain the invariant.\n\n## Regarding uniqueness of items\n\n#### No guarantees are made with regards to the uniqueness of items in the structure.\n\nUsing the `select` function (or `selectWith`, etc) selects the first matching\nitem as expected:\n\n```purescript\nxs = SF.fromFoldable [1,2,3] # SF.selectWith (\\x -\u003e x \u003c 3)\n\nSF.selected xs -- Just 1\n```\n\nHowever, when using `mapSelected` (or `foldrSelected`) to map a function `f`\nover a `SelectionFoldable` where the selected item appears more than once in the\nlist, `true` will be passed as the `IsSelected` argument for each instance of\nthe selected item:\n\n```purescript\n-- Here, both the first and last elements are equal to the selected item.\nxs = SF.fromFoldable [1,2,1] # SF.select 1\n\nmapSelected (\\isSelected x -\u003e if isSelected then \"a\" else \"b\") xs\n-- (SelectionFoldableWithData [\"a\",\"b\",\"a\"] Just (Tuple unit \"a\")))\n-- Note how both the first and last items were treated as if they were selected\n```\n\n## Developing\n\n1. Install purescript: `npm install -g purescript`\n2. Install  bower: `npm install -g bower`\n3. Install pulp: `npm install -g pulp`\n4. Install dependencies: `npm install \u0026\u0026 bower install`\n5. Run tests: `pulp test`\n\n## License\n\nLicensed under a BSD 3-Clause license\n\n## Documentation\n\n- Module documentation is [published on Pursuit](https://pursuit.purescript.org/packages/purescript-selection-foldable).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjamieyung%2Fpurescript-selection-foldable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjamieyung%2Fpurescript-selection-foldable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjamieyung%2Fpurescript-selection-foldable/lists"}