{"id":13709512,"url":"https://github.com/rowtype-yoga/purescript-record-studio","last_synced_at":"2026-01-18T17:33:54.986Z","repository":{"id":62637946,"uuid":"350102987","full_name":"rowtype-yoga/purescript-record-studio","owner":"rowtype-yoga","description":"📀 You finally scored a record deal.","archived":false,"fork":false,"pushed_at":"2023-04-11T08:23:31.000Z","size":73,"stargazers_count":11,"open_issues_count":1,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-26T09:53:29.100Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"PureScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit-0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rowtype-yoga.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-03-21T19:51:56.000Z","updated_at":"2025-01-17T10:21:52.000Z","dependencies_parsed_at":"2024-05-08T00:32:19.800Z","dependency_job_id":"846bd36c-2eba-498f-a66e-1b8abb9a87d2","html_url":"https://github.com/rowtype-yoga/purescript-record-studio","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rowtype-yoga%2Fpurescript-record-studio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rowtype-yoga%2Fpurescript-record-studio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rowtype-yoga%2Fpurescript-record-studio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rowtype-yoga%2Fpurescript-record-studio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rowtype-yoga","download_url":"https://codeload.github.com/rowtype-yoga/purescript-record-studio/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252721080,"owners_count":21793748,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-08-02T23:00:40.516Z","updated_at":"2025-05-06T16:31:52.941Z","avatar_url":"https://github.com/rowtype-yoga.png","language":"PureScript","funding_links":[],"categories":["Data types"],"sub_categories":[],"readme":"# purescript-record-studio 📀📀📀\n\nYou finally scored a record deal.\n\n## Usage guide\n\n### Assert two records have the same keys with `SameKeys`\n\n```purescript\n-- An example of a function that requires `{|r1}` and `{|r2}` to have the same keys\nsameKeys :: forall r1 r2. SameKeys r1 r2 =\u003e {|r1} -\u003e {|r2} -\u003e Unit\nsameKeys _ _ = unit\nlet _ = sameKeys { b: \"hi\", a: 4, c: 4 } { b: \"hu\", a: \"ha\" }\n-- Won't compile: The key \"c\" is missing from the second record\n```\n\n### Merge records with `//`\nEasily merge two records:\n\n```purescript\n{ a: 5, b: \"B\" } // { b: false, c: \"c\" }\n-- { a: 5, b: false, c: \"c\" }\n```\n\nThis is similar to the `...` operator in ES6:\n\nPureScript:\n```purescript\nimport Record.Studio ((//))\nrec1 = { a: 1 }\nrec2 = { b: 4, c: 8 }\nresult = rec1 // rec2\n```\n\nJS:\n```js\nconst rec1 = { a: 1 }\nconst rec2 = { b: 4, c: 8 }\nconst result = { ...rec1, ...rec2 }\n```\n\n### Shrink records with `shrink`\nEasily adjust a record with too many keys:\n```purescript\nimport Record.Studio (shrink)\n-- We want to call this\n-- fn :: { a :: Int } -\u003e Int\n\n-- We have this\nmyRec :: { a :: Int, b :: String }\nmyRec = { a: 4, b: \"Hello!\" }\n\n-- Use shrink!\nresult = fn (shrink myRec)\n```\n\n### Get a record's keys at runtime with `keys`\n```purescript\nimport Record.Studio (keys)\n\ntheKeys :: Array String\ntheKeys = keys { a: 3, b: \"ooh\" }\n-- [\"a\", \"b\"]\n```\n\n### `sequenceRecord`\nRecursively sequence a type constructor out of a record.\n\n```purescript\nlet\n    input :: SequenceInput\n    input =\n    { a: Just 10\n    , b: \"hello\"\n    , c:\n        { d: Just \"world\"\n        , e: true\n        , f: { g: Just true }\n        }\n    , h: 10\n    }\n\n    expected :: Maybe SequenceOutput\n    expected = Just\n    { a: 10\n    , b: \"hello\"\n    , c:\n        { d: \"world\"\n        , e: true\n        , f: { g: true }\n        }\n    , h: 10\n    }\n(sequenceRecord input) `shouldEqual` expected\n```\n\n### `mapUniformRecord`\n\nRecursively map a function over a record where all entries have the same value.\nThis is often better at type inference than `mapRecord`\n```purescript\n  (mapUniformRecord (_ + 1) { a: 1, b: 2 }) `shouldEqual` { a: 2, b: 3}\n```\n\n### `mapRecord`\n\nRecursively map a function over a record.\n```purescript\nlet\n    input :: MapInput\n    input =\n    { a: 10\n    , b: \"hello\"\n    , c:\n        { d: Just \"world\"\n        , e: 20\n        , f: { g: true, h: 30 }\n        }\n    , i: 40\n    }\n\n    f :: Int -\u003e String\n    f i = show (i + 1)\n\n    expected :: MapOutput\n    expected =\n    { a: \"11\"\n    , b: \"hello\"\n    , c:\n        { d: Just \"world\"\n        , e: \"21\"\n        , f: { g: true, h: \"31\" }\n        }\n    , i: \"41\"\n    }\n(mapRecord f input) `shouldEqual` expected\n```\n\n### `mapRecordKind`\n\nRecursively map a natural transformation over a record.\n\n```purescript\n let\n    input :: MapKInput\n    input =\n    { a: Right 10\n    , b: \"hello\"\n    , c:\n        { d: Left \"world\"\n        , e: 20\n        , f: { g: Right true, h: Left \"broken\" }\n        }\n    , i: Just 40\n    }\n\n    nt :: Either String ~\u003e Maybe\n    nt = hush\n\n    expected :: MapKOutput\n    expected =\n    { a: Just 10\n    , b: \"hello\"\n    , c:\n        { d: Nothing\n        , e: 20\n        , f: { g: Just true, h: Nothing }\n        }\n    , i: Just 40\n    }\n(mapRecordKind nt input) `shouldEqual` expected\n```\n\n### `key` \n\nGet the only field name of a Record with one field as a `Proxy`\n\n```purescript\nSingletonRecord.key { foo: unit } `shouldEqual` (Proxy :: Proxy \"foo\")\n```\n\n## Licence\nThis is a fork of [heterogeneous-extrablatt](https://github.com/sigma-andex/purescript-heterogeneous-extrablatt), which is licenced under MIT. See the [original licence](./LICENCES/heterogeneous-extrablatt.LICENCE). This work is similarly licenced under [MIT](./LICENCE).\nIt includes part of [`purescript-record-extra`](https://github.com/justinwoo/purescript-record-extra) as an inline dependency, which is licenced under MIT, see [original licence](./LICENCES/record-extra.LICENCE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frowtype-yoga%2Fpurescript-record-studio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frowtype-yoga%2Fpurescript-record-studio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frowtype-yoga%2Fpurescript-record-studio/lists"}