kolektiv

Andrew Cherry

Aether — Update

NOTE: This article has been superceded by later changes to the Aether library in late 2015. See the Aether site for up to date information.

Just before the weekend, I pushed out 4.0 of Aether (yes, that does seem a high version number, but that’s what happens with SemVer!) It’s a good update I hope, as it makes one aspect much better – isomorphisms.

Previously, Isomorphisms were simply treated as another kind of lens, and composed as such. However, this didn’t really work for cases where you had chains of isomorphisms composed with a partial lens. Even if all of the isomorphisms would succeed, you’d never be able to set a value if the existing partial lens returned None. This is because composition worked “left to right”, so the chain of composition would halt when a partial lens returned None (setting a lens involves getting the value “left” of the lens to set to, as a rough intuition).

The new model works better by making isomorphisms a first class concept – indeed they have their own type signature (and it’s very obvious):

type Iso<'a,'b> = ('a -> 'b) * ('b -> 'a)

Very simply – the pair of functions which map a to b and back. Partial isomorphisms are represented the same way, with the first function returning 'b option rather than 'b. Isomorphisms now also have their own composition operators for composing an isomorphism with a lens which solves the partial chain issue and they follow the exact same pattern as operators for composing lenses with lenses:

<--> (* Compose a total lens with a total isomorphism, giving a total lens *)
<-?> (* Compose a total lens with a partial isomorphism, giving a partial lens *)
<?-> (* Compose a partial lens with a total isomorphism, giving a partial lens *)
<??> (* Compose a partial lens with a partial isomorphism, giving a partial lens *)

Using these operators and signatures for defining and composing isomorphisms with lenses gives a much more effective and succinct way of dealing with isomorphisms in partial cases. The latest version of Aether is available through Nuget as always…