{"id":21517557,"url":"https://github.com/tek/cornea","last_synced_at":"2025-03-17T16:28:41.477Z","repository":{"id":56843258,"uuid":"175479931","full_name":"tek/cornea","owner":"tek","description":"classy optical monadic state","archived":false,"fork":false,"pushed_at":"2022-02-05T14:42:59.000Z","size":49,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-24T09:37:33.079Z","etag":null,"topics":["classy-optics","haskell","monaderror","monadstate"],"latest_commit_sha":null,"homepage":null,"language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tek.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}},"created_at":"2019-03-13T18:46:43.000Z","updated_at":"2022-02-05T14:43:02.000Z","dependencies_parsed_at":"2022-09-09T04:12:21.114Z","dependency_job_id":null,"html_url":"https://github.com/tek/cornea","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tek%2Fcornea","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tek%2Fcornea/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tek%2Fcornea/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tek%2Fcornea/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tek","download_url":"https://codeload.github.com/tek/cornea/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244068300,"owners_count":20392790,"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":["classy-optics","haskell","monaderror","monadstate"],"created_at":"2024-11-24T00:42:29.454Z","updated_at":"2025-03-17T16:28:41.441Z","avatar_url":"https://github.com/tek.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Intro\n\nClasses for accessing and mutating nested data types with corresponding adapter\nclasses for `MonadState`, `MonadReader` and `MonadError`. Inspired by the\n[next level mtl with classy optics] talk.\n\n[Hackage]\n\n# Internals\n\nLenses and Prisms from [lens] are autogenerated with [TH] by splicing with\n`deepPrisms` and `deepLenses`.\nThe generator recurses into single-field constructors and record fields if\nthere are instances of `DeepPrisms` or `DeepLenses` for their parameter types.\n\n# Example\n\nFor `MonadError`:\n\n```haskell\n{-# LANGUAGE TemplateHaskell #-}\n\nimport Cornea (MonadDeepError(throwHoist))\nimport Control.Monad.Trans.Except (runExceptT)\nimport Data.DeepPrisms (deepPrisms)\n\nnewtype Error = Error String\n\nnewtype Inner = Inner Error\ndeepPrisms ''Inner\n\ndata Mid = Mid Inner\ndeepPrisms ''Mid\n\nnewtype Outer = Outer Mid\ndeepPrisms ''Outer\n\nthrowDeep :: MonadDeepError e Inner m =\u003e m ()\nthrowDeep = throwHoist (Inner (Error \"boom\"))\n\nmain :: IO (Either Outer ())\nmain = runExceptT throwDeep\n```\n\nIn `main`, `MonadError Outer IO` and `DeepPrisms Outer Inner` are summoned.\n\nAnalogously for `MonadState`:\n\n```haskell\n{-# LANGUAGE TemplateHaskell #-}\n\nimport Cornea (MonadDeepState(get, gets, put))\nimport Control.Monad.Trans.State (execStateT)\nimport Data.DeepLenses (deepLenses)\n\nnewtype S = S Int\n\nnewtype Inner = Inner { _innerS :: S }\ndeepLenses ''Inner\n\ndata Mid = Mid { _midInner :: Inner }\ndeepLenses ''Mid\n\nnewtype Outer = Outer { _outerMid :: Mid }\ndeepLenses ''Outer\n\nstateDeep :: MonadDeepState s Inner m =\u003e m ()\nstateDeep = do\n  (Inner (S a)) \u003c- get\n  b \u003c- gets $ \\(Inner (S b)) -\u003e b\n  put (Inner (S (a + b + 3)))\n\nmain :: IO Outer\nmain = do\n  execStateT stateDeep (Outer (Mid (Inner (S 5))))\n```\n\n`MonadReader` works basically the same as `MonadState`.\n\n[lens]: https://hackage.haskell.org/package/lens\n[TH]: https://hackage.haskell.org/package/template-haskell\n[next level mtl with classy optics]: https://github.com/gwils/next-level-mtl-with-classy-optics\n[Hackage]: https://hackage.haskell.org/package/cornea\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftek%2Fcornea","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftek%2Fcornea","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftek%2Fcornea/lists"}