HORIZON HASKELLDocslts/ghc-9.10.x248f8f02026-10-05Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · 248f8f0 · 2026-10-05

Moduleoptics-core-0.4.1.1Haskell2010

Optics.Iso

An Isomorphism expresses the fact that two types have the same structure, and hence can be converted from one to the other in either direction.

  • 3 types
  • 1 class
  • 16 values

Formation

2 declarations

Introduction

1 declaration
valueiso :: (s -> a) -> (b -> t) -> Iso s t a b
#

Build an iso from a pair of inverse functions.

If you want to build an Iso from the van Laarhoven representation, use isoVL from the optics-vl package.

Elimination

0 declarations

An Iso is in particular a Getter, a Review and a Setter, therefore you can specialise types to obtain:

view   :: Iso' s a -> s -> a
review :: Iso' s a -> a -> s
over   :: Iso s t a b -> (a -> b) -> s -> t
set    :: Iso s t a b ->       b  -> s -> t

If you want to view a type-modifying Iso that is insufficiently polymorphic to be used as a type-preserving Iso', use getting:

view . getting :: Iso s t a b -> s -> a

Computation

0 declarations
view   (iso f g) ≡ f
review (iso f g) ≡ g

Well-formedness

0 declarations

The functions translating back and forth must be mutually inverse:

view i . review i ≡ id
review i . view i ≡ id

Additional introduction forms

13 declarations
valueequality :: (s ~ a, t ~ b) => Iso s t a b
#

Capture type constraints as an isomorphism.

Note: This is the identity optic:

Example1 expression
:t view equalityview equality :: a -> a
valuecoerced :: (Coercible s a, Coercible t b) => Iso s t a b
#

Data types that are representationally equal are isomorphic.

Example1 expression
view coerced 'x' :: Identity CharIdentity 'x'
valuecoercedTo :: Coercible s a => Iso' s a
#

Type-preserving version of coerced with type parameters rearranged for TypeApplications.

Example1 expression
newtype MkInt = MkInt Int deriving Show
Example1 expression
over (coercedTo @Int) (*3) (MkInt 2)MkInt 6
valuecoerced1 :: (Coercible s (f s), Coercible a (f a)) => Iso (f s) (f a) s a
#

Special case of coerced for trivial newtype wrappers.

Example1 expression
over (coerced1 @Identity) (++ "bar") (Identity "foo")Identity "foobar"
valuenon :: Eq a => a -> Iso' (Maybe a) a
#

If v is an element of a type a, and a' is a sans the element v, then non v is an isomorphism from Maybe a' to a.

non ≡ non' . only

Keep in mind this is only a real isomorphism if you treat the domain as being Maybe (a sans v).

This is practically quite useful when you want to have a Data.Map.Map where all the entries should have non-zero values.

Example1 expression
Map.fromList [("hello",1)] & at "hello" % non 0 %~ (+2)fromList [("hello",3)]
Example1 expression
Map.fromList [("hello",1)] & at "hello" % non 0 %~ (subtract 1)fromList []
Example1 expression
Map.fromList [("hello",1)] ^. at "hello" % non 01
Example1 expression
Map.fromList [] ^. at "hello" % non 00

This combinator is also particularly useful when working with nested maps.

e.g. When you want to create the nested Data.Map.Map when it is missing:

Example1 expression
Map.empty & at "hello" % non Map.empty % at "world" ?~ "!!!"fromList [("hello",fromList [("world","!!!")])]

and when have deleting the last entry from the nested Data.Map.Map mean that we should delete its entry from the surrounding one:

Example1 expression
Map.fromList [("hello", Map.fromList [("world","!!!")])] & at "hello" % non Map.empty % at "world" .~ NothingfromList []

It can also be used in reverse to exclude a given value:

Example1 expression
non 0 # rem 10 4Just 2
Example1 expression
non 0 # rem 10 5Nothing
valuenon' :: Prism' a () -> Iso' (Maybe a) a
#

non' p generalizes non (p # ()) to take any unit Prism

This function generates an isomorphism between Maybe (a | isn't p a) and a.

Example1 expression
Map.singleton "hello" Map.empty & at "hello" % non' _Empty % at "world" ?~ "!!!"fromList [("hello",fromList [("world","!!!")])]
Example1 expression
Map.fromList [("hello", Map.fromList [("world","!!!")])] & at "hello" % non' _Empty % at "world" .~ NothingfromList []
valueanon :: a -> (a -> Bool) -> Iso' (Maybe a) a
#

anon a p generalizes non a to take any value and a predicate.

anon a ≡ non' . nearly a

This function assumes that p a holds True and generates an isomorphism between Maybe (a | not (p a)) and a.

Example1 expression
Map.empty & at "hello" % anon Map.empty Map.null % at "world" ?~ "!!!"fromList [("hello",fromList [("world","!!!")])]
Example1 expression
Map.fromList [("hello", Map.fromList [("world","!!!")])] & at "hello" % anon Map.empty Map.null % at "world" .~ NothingfromList []
valuecurried :: Iso ((a, b) -> c) ((d, e) -> f) (a -> b -> c) (d -> e -> f)
#

The canonical isomorphism for currying and uncurrying a function.

curried = iso curry uncurry
Example1 expression
view curried fst 3 43
valueflipped :: Iso (a -> b -> c) (a' -> b' -> c') (b -> a -> c) (b' -> a' -> c')
#

The isomorphism for flipping a function.

Example1 expression
(view flipped (,)) 1 2(2,1)
valueinvoluted :: (a -> a) -> Iso' a a
#

Given a function that is its own inverse, this gives you an Iso using it in both directions.

involuted ≡ join iso
Example1 expression
"live" ^. involuted reverse"evil"
Example1 expression
"live" & involuted reverse %~ ('d':)"lived"

Additional elimination forms

3 declarations
valuewithIso :: Iso s t a b -> ((s -> a) -> (b -> t) -> r) -> r
#

Extract the two components of an isomorphism.

valueau :: Functor f => Iso s t a b -> ((b -> t) -> f s) -> f a
#

Based on ala from Conor McBride's work on Epigram.

This version is generalized to accept any Iso, not just a newtype.

Example1 expression
au (coerced1 @Sum) foldMap [1,2,3,4]10

You may want to think of this combinator as having the following, simpler type:

au :: Iso s t a b -> ((b -> t) -> e -> s) -> e -> a

Combinators

0 declarations

The re combinator can be used to reverse an Iso, and the mapping combinator to lift an Iso to an Iso on functorial values.

re      ::                           Iso s t a b -> Iso b a t s
mapping :: (Functor f, Functor g) => Iso s t a b -> Iso (f s) (g t) (f a) (g b)

Subtyping

1 declaration
datadata An_Iso
#

Tag for an iso.

Instances41ReversibleOptic, Is, ArrowOptic, JoinKinds, ToReadOnly, MappingOptic, …