Proposing std.typecons : Optional (with PR)
Johannes Loher
johannes.loher at fg4f.de
Tue Jun 11 22:49:38 UTC 2019
Am 11.06.19 um 12:01 schrieb FeepingCreature:
> Ranges are not monads. We may wish we had a concept of monads
> but we don't; ranges are not a general replacement for any conceivable
> container.
Yes, ranges are not a general replacement for the concept of a monad,
but the concept "range" is basically a monad:
Type constructor: For any type T, a range of T is something for that
isInputRange!T is true (yes, technically that's not a single "type", but
rather something like a typeclass, but it is close enough).
Type converter (unit / return): unit: T -> Range T, x -> only(x)
Combinator (bind / >>=): (Range T, T → Range U) → Range U, (r,f) ->
r.map!f.joiner
Obviously, using these definitions, unit is both a left- and
right-identity for bind and bind is essentially associative. So aside
from the fact that there is no "real" type constructor because there is
no actual general range type, I believe this qualifies the concept of a
range as a monad.
All of this aside, I agree that ranges are not a good general
replacement for every container. I do however disagree with you in this
specific case. I personally have to use Java a lot at work and I am
regularly annoyed by the fact, that Optionals in Java are not Iterables
(or Streams...). I like the aproach of Scala's and Vavr's "Option" much
more, which implement the corresponding Iterable interfaces. It makes a
lot of things just that much easier, e.g.
List.of(Optional.of(42), Optional.of(1234)).stream()
.filter(Optional::isPresent)
.map(Optional::get)
becomes
List.of(Optional.of(42), Optional.of(1234)).stream()
.flatMap(o -> o)
or in D:
only(optional(42), optional(1234))
.filter!(o -> o.present)
.map!(o -> o.value)
becomes
only(optional(42), optional(1234))
.joiner
Of course it is still debatable if we want this, but in my opinion this
is a great improvement.
If we decide against Optional being a "real" optional type as used in
other more functional languages, I'm actually against adding it to the
standard library. I'd much prefer to fix the `alias get this` issue of
Nullable in that case.
Don't get me wrong however, I'd love a real Optional type. But so far,
the `optional` dub package works reasonably well for me. I like the
pattern matching functionality in particular, but it also provides other
goodies you'd expect from a real optional type, too, e.g. `orElse`. Your
suggested implementation is lacking these unfortunately.
More information about the Digitalmars-d
mailing list