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.

Reply via email to