Barlow lens increases your magnification and let's you see the stars ✨
In other words, barlow lens makes creating complex lenses such as record lenses super simple.
spago install barlow-lens
sky =
{ zodiac:
{ virgo:
{ alpha: "Spica"
}
}
}
view (barlow (key :: _ "zodiac.virgo.alpha")) sky
-- "Spica"
over (barlow (key :: _ "zodiac.virgo.alpha")) toUpper sky
-- { zodiac: { virgo: { alpha: "SPICA" } } }
-- view (barlow (key :: _ "zodiac.virgo.alfa")) sky
-- doesn't compile
Barlow supports lens creation for the following types:
- 📦🐈
Maybe
- 🤷🏽♀️
Either
- 📜
Array
- 🎁
Newtype
- 🤖
Data types
(experimental)
Use ?
to zoom into a Maybe
.
sky =
{ zodiac:
Just
{ virgo:
Just
{ alpha: Just "Spica"
}
}
}
preview (barlow (key :: _ "zodiac?.virgo?.alpha?")) sky
Use <
for Left
and >
for Right
to zoom into an Either
.
sky =
{ zodiac:
Right
{ virgo:
Just
{ alpha: Left "Spica"
}
}
}
preview (barlow (key :: _ "zodiac>.virgo?.alpha<")) sky
Use +
to zoom into Traversable
s like Array
.
sky =
{ zodiac:
[ { virgo:
Just
{ star: "Spica"
}
}
, { virgo:
Just
{ star: "Serpentis"
}
}
]
}
over (barlow (key :: _ "zodiac+.virgo?.star")) toUpper sky
Use !
to zoom into a Newtype
.
newtype Alpha = Alpha { alpha :: String }
instance alphaNT :: Newtype Alpha { alpha :: String }
sky =
{ zodiac:
Just
{ virgo:
Alpha { alpha: "Spica"
}
}
}
preview (barlow (key :: _ "zodiac?.virgo!.alpha")) sky
Note: This feature is still experimental and might slightly change in the future 🛸.
Barlow now supports zooming into arbitrary sum and product data types as long as there is a Generic
instance.
Use <
and >
to zoom into the left and right cases of your sum type.
data Zodiac
= Carina String | Virgo String | CanisMaior String
derive instance genericZodiac :: Generic Zodiac _
instance showZodiac :: Show Zodiac where
show = genericShow
sky =
{ zodiac: CanisMaior "Sirius"
}
-- Twice to the right for CanisMaior, once to the left for the String
actual = preview (barlow (key :: _ "zodiac>><")) sky
-- Just "Sirius"
Use <
and >
to zoom into the left and right cases of your product type.
data Zodiac
= Virgo { alpha :: String } { beta :: String } { gamma :: String } { delta :: String }
derive instance genericZodiac :: Generic Zodiac _
instance showZodiac :: Show Zodiac where
show = genericShow
sky =
{ zodiac:
{ virgo:
Virgo { alpha : "Spica"} { beta: "β Vir"} { gamma: "γ Vir B"} { delta: "δ Vir"}
}
}
actual = preview (barlow (key :: _ "zodiac.virgo>>>.delta")) sky
-- (Just "δ Vir")
And you can of course combine them. It is more readable if you separate your sum lens from your product lens with a .
dot.
data Zodiac
= Carina { alpha :: String } | Virgo { alpha :: String } { beta :: String } { gamma :: String } { delta :: String } | CanisMaior String
derive instance genericZodiac :: Generic Zodiac _
derive instance eqZodiac :: Eq Zodiac
instance showZodiac :: Show Zodiac where
show = genericShow
sky =
{ zodiac:
{ virgo:
Virgo { alpha : "Spica"} { beta: "β Vir"} { gamma: "γ Vir B"} { delta: "δ Vir"}
}
}
over (barlow (key :: _ "zodiac.virgo><.>>>.delta")) toUpper sky
-- { zodiac: { virgo: Virgo9 { alpha : "Spica"} { beta: "β Vir"} { gamma: "γ Vir B"} { delta: "Δ VIR"} } }
This lib was heavily inspired by this incredible blog post. Thanks also to @i-am-the-slime for pushing further and reviewing my PRs.