To expand, Go's type system is relatively rudimentary. The lack of option types[0] leads to this fairly common, verbose Go pattern:
func DoFoo(Foo foo) Cat {
bar, err := GetBar(foo)
if (err != nil) { return nil }
baz, err := GetBaz(bar)
if (err != nil) { return nil }
cat, err := GetCat(baz)
if (err != nil) { return nil }
return cat
}
Option types add metadata to a type, essentially combining `bar` and `err` into a single variable. Let `Maybe x` mean a function will return `Something x` or `Nothing`. For example (in hypothetical Go):
func DoFoo(Foo foo) Maybe Cat {
bar := GetBar(foo)
if (bar.(type) == Nothing) { return Nothing }
baz := GetBaz(bar)
if (baz.(type) == Nothing) { return Nothing }
cat := GetCat(baz)
if (cat.(type) == Nothing) { return Nothing }
return cat
}
Since this is such a common pattern, Haskell has a bind operator (`>>=`) to take advantage of option types by passing the output as the input of the next function if it's a `Something`, or return `Nothing`.
func DoFoo(Foo foo) Maybe Cat {
return GetBar foo >>= GetBaz >>= GetCat
}
If you care about why something failed, use an `Either` instead of a `Maybe`. In a language that supports algebraic data types, you could create your own sum type instead.
[0] https://en.wikipedia.org/wiki/Option_type