Option types and pattern matching.
Edmund Smith via Digitalmars-d
digitalmars-d at puremagic.com
Mon Oct 26 08:58:36 PDT 2015
On Monday, 26 October 2015 at 14:13:20 UTC, TheFlyingFiddle wrote:
> On Monday, 26 October 2015 at 11:40:09 UTC, Edmund Smith wrote:
>> Scala's Option is really nice on the other hand since you
>> can/should pattern match).
> Don't really see a point in an optional type if can access the
> underlying
> value without first checking if it's there.
The key difference with (exhaustive) pattern matching is that it
*is* the check that the value is there. Pattern matching enforces
the existence of an on-nothing clause for Optional, on-error for
Error, on-Leaf and on-Branch for Bintrees, etc.
And even with nice higher-order functions, plain pattern matching
is quite valuable for finely controlled error/resource handling,
and I often see it in Rust code as well as Scala (and I've seen
it used in Haskell occasionally too). A brief, contrived example
use-case:
//External code that disallows monadic int[]
void processThatMustOccur(int[] data);
...
Option!File findFile(string fname);
Result!(int[]) parseInts(File file);
//verbose for clarity
void parseMatches(string path) {
Option!File ofile = path.findFile();
//Static guarantee of handling value not present
ofile match {
None() => {
//Handle error for no file found, retry with new path
}
//The existence of file is effectively proof that ofile
is present
Some(file) => {
Option!(int[]) odata = file.parseInts();
odata match {
Success(data) =>
processThatMustOccur(preProcess(data));
Error(error) =>
//Handle error for bad parse, backtrack
depends on error
}
}
}
//Continue after processing data
}
void parseMonadic(string path) {
path.findFile()
.bind!parseInts()
.bind!(map!preProcess)
.bind!processThatMustOccur()
.onFailure!backTrack
//How can we backtrack a variable amount easily?
//Continue after processing data
}
The error control loss can be mostly avoided by using an
appropriate error monad or API design, but there's still the
issue of interfacing with non-monadic code.
It essentially provides a guarantee that the equivalent of 'T
get();' will handle errors, like having a checked exception
version 'T get() throws OnNotPresent;' instead. It also scales up
much better than having these checked exceptions on not-present
ADT accesses.
More information about the Digitalmars-d
mailing list