This is the eleventh post in my ongoing series covering the abstractions in Sasa. Previous posts:
- Sasa.Parsing - type-safe, extensible lexing and parsing framework
- Sasa.Dynamics - type-safe polytypic/reflective programming
- Sasa.Func - Type-Safe Delegate Combinators
- Sasa.Option - Handling Optional Values
- Sasa.Result - Handling Exceptional Values
- Sasa.Numbers - Generic Number Extensions
- Sasa.Strings - General String Extensions
- Sasa.Types - Runtime Types And CLR Metadata
- Sasa.Weak - Typed Weak References
- Sasa's Tuples
I covered some of Sasa's core interfaces previously, but I shall provide a more thorough treatment here.
Sasa.IValue<T>
Fundamentally, programs manipulate values. These values can often be classified into various categories depending on how they can be manipulated or computed. At the most basic level, we have a simple value represented by Sasa.IValue<T>. IValue<T> provides only a single property to access the encapsulated value:
IValue<int> x = new Immutable<int>(3); Console.WriteLine(x.Value); // output: // 3
This demonstrates the use of a simple immutable value class, but the Value property need not be so simple. It can even throw exceptions in some cases. For instance, as covered in a previous article Sasa.Result<T>.Value throws InvalidOperationException if the result was an error instead of a value.
Sasa.IRef<T>.Value
Sasa.IRef<T>.Value extends the read-only Sasa.IValue<T> with a setter for the Sasa.IRef<T>.Value property:
IRef<int> x = new Ref<int>(3); x.Value = 999; Console.WriteLine(x.Value); // output: // 999
Sasa.IVolatile<T>.TryGetValue
Some values may or may not be present, and it's often necessary to check for the presence of a legitimate value and to obtain that value in a single step. Enter IVolatile<T>, which provides a standard interface for the common TryGetValue pattern:
IVolatile<int> withValue = new Option<int>(3); int value; if (withValue.TryGetValue(out value)) Console.WriteLine(value); IVolatile<int> noValue = Option<int>.None; if (noValue.TryGetValue(out value)) Console.WriteLine(value); // output: // 3
Sasa.IResolvable<T>.HasValue
Similar to IVolatile<T>, IResolvable<T> standardizes an interface for values that may or may not be present by exporting a HasValue property:
IResolvable<int> withValue = new Option<int>(3); if (withValue.HasValue) Console.WriteLine(withValue.Value); IResolvable<int> noValue = Option<int>.None; if (noValue.HasValue) Console.WriteLine(noValue.Value); // output: // 3
Sasa.IOptional<T>
Sasa.IOptional<T> is an interface that implements IVolatile<T>, IResolvable<T>, and IValue<T>. It is implemented by many of the abstractions in Sasa that encapsulate values, like Sasa.Option<T> and Sasa.Result<T>.
Sasa.IResult<T>
Sasa.IResult<T> describes values that resolve either to a value or an error. It's an abstraction that implements IOptional<T>, IVolatile<T>, IResolvable<T>, and IValue<T>, and also exports an Error property:
IResult<int> withValue = new Result<int>(3); if (withValue.HasValue) Console.WriteLine(withValue.Value); IResult<int> noValue = Result.Fail<int>(new ArgumentException()); if (noValue.HasValue) Console.WriteLine(noValue.Value); else Console.WriteLine("Error: {0}", noValue.Error.Message); // output: // 3 // Error: ArgumentException ...
This interface is implemented by Sasa.Result<T> and a few other abstractions in Sasa. Sasa.Result also implements the LINQ query pattern on IResult<T> instances.
Comments