cornea: classy optical monadic state

[ lens, library ] [ Propose Tags ]

Please see the README on GitHub at https://github.com/tek/cornea


[Skip to Readme]
Versions [faq] 0.2.0.0, 0.2.1.0, 0.2.2.0
Dependencies base (>=4.7 && <5), lens (>=4.16.1 && <4.17), mtl (>=2.2.2 && <2.3), template-haskell (>=2.13.0.0 && <2.14), th-abstraction (>=0.2.10.0 && <0.3), transformers (>=0.5.5.0 && <0.6) [details]
License LicenseRef-OtherLicense
Copyright 2019 Torsten Schmits
Author Torsten Schmits
Maintainer tek@tryp.io
Category Lens
Home page https://github.com/tek/cornea#readme
Bug tracker https://github.com/tek/cornea/issues
Source repo head: git clone https://github.com/tek/cornea
Uploaded by tek at Fri Mar 15 18:48:10 UTC 2019
Distributions NixOS:0.2.2.0
Downloads 313 total (63 in the last 30 days)
Rating 2.0 (votes: 1) [estimated by rule of succession]
Your Rating
  • λ
  • λ
  • λ
Status Hackage Matrix CI
Docs not available [build log]
All reported builds failed as of 2019-03-15 [all 3 reports]

Modules

  • Control
    • Monad
      • Control.Monad.DeepError
      • Control.Monad.DeepState
  • Data
    • Data.DeepLenses
    • Data.DeepPrisms

Downloads

Maintainer's Corner

For package maintainers and hackage trustees


Readme for cornea-0.2.2.0

[back to package description]

Intro

Classes for accessing and mutating nested data types with corresponding adapter classes for MonadState and MonadError. Inspired by the next level mtl with classy optics talk.

Hackage

Internals

Lenses and Prisms from lens are autogenerated with TH by splicing with deepPrisms and deepLenses. The generator recurses into single-field constructors and record fields if there are instances of DeepPrisms or DeepLenses for their parameter types.

Example

For MonadError:

{-# LANGUAGE TemplateHaskell #-}

import Control.Monad.DeepError (MonadDeepError(throwHoist))
import Control.Monad.Trans.Except (runExceptT)
import Data.DeepPrisms (deepPrisms)

newtype Error = Error String

newtype Inner = Inner Error
deepPrisms ''Inner

data Mid = Mid Inner
deepPrisms ''Mid

newtype Outer = Outer Mid
deepPrisms ''Outer

throwDeep :: MonadDeepError e Inner m => m ()
throwDeep = throwHoist (Inner (Error "boom"))

main :: IO (Either Outer ())
main = runExceptT throwDeep

In main, MonadError Outer IO and DeepPrisms Outer Inner are summoned.

Analogously for MonadState:

{-# LANGUAGE TemplateHaskell #-}

import Control.Monad.DeepState (MonadDeepState(get, gets, put))
import Control.Monad.Trans.State (execStateT)
import Data.DeepLenses (deepLenses)

newtype S = S Int

newtype Inner = Inner { _innerS :: S }
deepLenses ''Inner

data Mid = Mid { _midInner :: Inner }
deepLenses ''Mid

newtype Outer = Outer { _outerMid :: Mid }
deepLenses ''Outer

stateDeep :: MonadDeepState s Inner m => m ()
stateDeep = do
  (Inner (S a)) <- get
  b <- gets $ \(Inner (S b)) -> b
  put (Inner (S (a + b + 3)))

main :: IO Outer
main = do
  execStateT stateDeep (Outer (Mid (Inner (S 5))))