Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#290] Add Universum.Lens module #291

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,11 @@ Then, some commonly used types: `Map/HashMap/IntMap`, `Set/HashSet/IntSet`, `Seq
`deepseq` is exported. For instance, if you want to force deep evaluation of some value (in IO),
you can write `evaluateNF a`. WHNF evaluation is possible with `evaluateWHNF a`.

We also reexport big chunks of these libraries: `mtl`, `stm`, `microlens`, `microlens-mtl`.
`(.^)`, `(.~)` and some other optics-related functions and operators are exported in
`Universum.Lens` module.
This module is not included in `Universum` module so it requires explicit `import`.

We also reexport big chunks of `mtl`, `stm`.

[`Bifunctor`](http://hackage.haskell.org/package/base-4.9.1.0/docs/Data-Bifunctor.html)
type class with useful instances is exported.
Expand Down
79 changes: 11 additions & 68 deletions src/Universum.hs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ Below is a short description of what you can find under different modules:
* __"Universum.Function"__: almost everything from "Data.Function" module.
* __"Universum.Functor"__: reexports from "Data.Functor", "Data.Bifunctor",
other useful 'Functor' combinators.
* __"Universum.Lens"__: Some operators and functions for using lenses.
Not exported by "Universum" module by default, so, if more functionality is needed,
@microlens@ or @lens@ packages can be used without conflicts of names.
* __"Universum.Lifted"__: lifted to 'MonadIO' functions to work with console,
files, 'IORef's, 'MVar's, etc.
* __"Universum.List"__: big chunk of "Data.List", 'NonEmpty' type and
Expand Down Expand Up @@ -80,18 +83,7 @@ module Universum
, module Universum.TypeOps
, module Universum.VarArg

-- * Lenses
, Lens
, Lens'
, Traversal
, Traversal'
, over
, set
, (%~)
, (.~)
, (^.)
, (^..)
, (^?)
-- * Lenses, see also __"Universum.Lens"__
, _1
, _2
, _3
Expand Down Expand Up @@ -123,24 +115,12 @@ import Universum.TypeOps
import Universum.VarArg

-- Lenses
import qualified Lens.Micro (ASetter, Getting, over, set, (%~), (.~), (^.),
(^..), (^?), _1, _2, _3, _4, _5)
import qualified Lens.Micro (Getting, Lens, _1, _2, _3, _4, _5)
import qualified Lens.Micro.Mtl (preuse, preview, use, view)
import Lens.Micro.Internal (Field1, Field2, Field3, Field4, Field5)

{-# DEPRECATED
Lens
, Lens'
, Traversal
, Traversal'
, over
, set
, (%~)
, (.~)
, (^.)
, (^..)
, (^?)
, _1
_1
, _2
, _3
, _4
Expand All @@ -152,56 +132,19 @@ import Lens.Micro.Internal (Field1, Field2, Field3, Field4, Field5)
"Use corresponding function from 'lens' or 'microlens' package"
#-}

type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t
type Lens' s a = Lens s s a a

type Traversal s t a b = forall f. Applicative f => (a -> f b) -> s -> f t
type Traversal' s a = Traversal s s a a

over :: Lens.Micro.ASetter s t a b -> (a -> b) -> s -> t
over = Lens.Micro.over

set :: Lens.Micro.ASetter s t a b -> b -> s -> t
set = Lens.Micro.set

(%~) :: Lens.Micro.ASetter s t a b -> (a -> b) -> s -> t
(%~) = (Lens.Micro.%~)

infixr 4 %~

(.~) :: Lens.Micro.ASetter s t a b -> b -> s -> t
(.~) = (Lens.Micro..~)

infixr 4 .~

(^.) :: s -> Lens.Micro.Getting a s a -> a
(^.) = (Lens.Micro.^.)

infixl 8 ^.

(^..) :: s -> Lens.Micro.Getting (Endo [a]) s a -> [a]
(^..) = (Lens.Micro.^..)

infixl 8 ^..

(^?) :: s -> Lens.Micro.Getting (First a) s a -> Maybe a
(^?) = (Lens.Micro.^?)

infixl 8 ^?

_1 :: Field1 s t a b => Lens s t a b
_1 :: Field1 s t a b => Lens.Micro.Lens s t a b
_1 = Lens.Micro._1

_2 :: Field2 s t a b => Lens s t a b
_2 :: Field2 s t a b => Lens.Micro.Lens s t a b
_2 = Lens.Micro._2

_3 :: Field3 s t a b => Lens s t a b
_3 :: Field3 s t a b => Lens.Micro.Lens s t a b
_3 = Lens.Micro._3

_4 :: Field4 s t a b => Lens s t a b
_4 :: Field4 s t a b => Lens.Micro.Lens s t a b
_4 = Lens.Micro._4

_5 :: Field5 s t a b => Lens s t a b
_5 :: Field5 s t a b => Lens.Micro.Lens s t a b
_5 = Lens.Micro._5

preuse :: MonadState s m => Lens.Micro.Getting (First a) s a -> m (Maybe a)
Expand Down
79 changes: 79 additions & 0 deletions src/Universum/Lens.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE Safe #-}

-- | Operators and functions compatible with lens constructed with
-- any of `lens` and `microlens` packages. Both those packages contain
-- operators, types, and functions defined here, so you can find all related
-- documentation there.

module Universum.Lens
( Lens
, Lens'
, Traversal
, Traversal'

, ASetter
, Getting

, over
, set
, get
, (%~)
, (.~)
, (^.)
, (^..)
, (^?)
) where


import Data.Maybe (Maybe (..))
import Universum.Applicative
import Universum.Function
import Universum.Functor
import Universum.Monoid

type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t
type Lens' s a = Lens s s a a

type Traversal s t a b = forall f. Applicative f => (a -> f b) -> s -> f t
type Traversal' s a = Traversal s s a a

type ASetter s t a b = (a -> Identity b) -> s -> Identity t

type Getting r s a = (a -> Const r a) -> s -> Const r s

over :: ASetter s t a b -> (a -> b) -> s -> t
over setter f = runIdentity . setter (Identity . f)

set :: ASetter s t a b -> b -> s -> t
set setter f = over setter (const f)

get :: s -> Getting a s a -> a
get s getter = getConst $ getter Const s

(%~) ::ASetter s t a b -> (a -> b) -> s -> t
(%~) = over

infixr 4 %~

(.~) :: ASetter s t a b -> b -> s -> t
(.~) = set

infixr 4 .~

(^.) :: s -> Getting a s a -> a
(^.) = get

infixl 8 ^.

(^..) :: s -> Getting (Endo [a]) s a -> [a]
s ^.. getter =
let endo = getConst $ getter (\x -> Const $ Endo (x :)) s in
appEndo endo []

infixl 8 ^..

(^?) :: s -> Getting (First a) s a -> Maybe a
s ^? getter = getFirst $ getConst $ getter (Const . pure) s

infixl 8 ^?
1 change: 1 addition & 0 deletions universum.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ library
Universum.Functor
Universum.Functor.Fmap
Universum.Functor.Reexport
Universum.Lens
Universum.Lifted
Universum.Lifted.Concurrent
Universum.Lifted.Env
Expand Down