-
Notifications
You must be signed in to change notification settings - Fork 7
OneCaseLenses
Problem 1
It doesn't satisfy the second lens law in all cases. That law says that if you set
any part
to produce a whole
, get
on that whole
will be Just part
. That works if the argument to set
is "dawn"
:
> Lens.set onlyDawn "dawn" |> Lens.get onlyDawn
Just "dawn" : Maybe String
But what if we set
to something other than "dawn"
. The code does this:
> Lens.set onlyDawn "not dawn"
"not dawn" : String
But what will get
do with "not dawn"
. According to the lens law, the result should be Just "not dawn"
.
But it's not:
> Lens.get onlyDawn "not dawn"
Nothing : Maybe String
I don't see any way this can be made to work. There are two cases for Lens.set onlyDawn "not-dawn"
. The first is that the result is some non-"dawn"
value. But then get
will produce Nothing
, which violates the law.
The second case is that Lens.set onlyDawn "not-dawn"
produces "dawn"
. get
would now produce a non-Nothing
value (specifically, Just "dawn"
). But the law demands that you get back what you set. "dawn"
isn't it.
Problem 2
valid : Lens.OneCase String Int
valid =
Lens.oneCase (String.toInt >> Result.toMaybe) toString
Problem 3
You can use b2c.set
lens to create an entirely new b
, and then apply a2b.set
to create an entirely new a
.
The tricky part is get
. You need to handle two a2b.get
cases:
-
a
is the wrong wrapper, in which case the wholeget
must returnNothing
. -
a
is the right wrapper, in which caseJust b
must be converted to eitherNothing
orJust c
, depending on the value ofb
. When you have aMaybe x
being converted to aMaybe y
,Maybe.andThen
will probably be useful.
oneCaseAndOneCase : Lens.OneCase a b -> Lens.OneCase b c -> Lens.OneCase a c
oneCaseAndOneCase (Tagged a2b) (Tagged b2c) =
let
get =
a2b.get >> Maybe.andThen b2c.get
set =
b2c.set >> a2b.set
in
Lens.oneCase get set
Problem 4
oneCaseToHumble : Lens.OneCase big small -> Lens.Humble big small
oneCaseToHumble (Tagged lens) =
let
set small big =
case lens.get big of
Nothing ->
big
Just _ ->
lens.set small
in
Lens.humble lens.get set
Problem 5
oneCaseAndClassic : Lens.OneCase a b -> Lens.Classic b c -> Lens.Humble a c
oneCaseAndClassic a2b b2c =
Compose.humbleAndHumble
(oneCaseToHumble a2b)
(Compose.classicToHumble b2c)