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