Reputation: 1273
I'm playing with a Maybe monad in TypeScript. My understanding of the concepts isn't great so I would welcome any feedback or suggestions. There are loads of JS examples, but I'm looking for something more strongly typed.
The usage would be something like:
var maybe = new Example.Maybe({ name: "Peter", age: 21 })
.ifF(p => p.age === 100) // is the person 100?
.returnF(p => p.name, "Unknown") // extract Maybe string of name
.getValue(); // unwrap the string from the Maybe
Because if/with/return are reserved words I have just added F to the end..
So far I have:
module Example
{
export class Maybe<T>
{
private val: T;
private hasv: boolean;
private static none = new Maybe(null);
constructor(value: T)
{
this.val = value;
this.hasv = (value != null);
}
/** True if Maybe contains a non-empty value
*/
hasValue(): boolean
{
return this.hasv;
}
/** Returns non-empty value, or null if empty
*/
getValue(): T
{
if (this.hasv) return this.val;
return null;
}
/** Turns this maybe into Maybe R or Maybe NONE if there is no value
*/
withF<R>(func: (v: T) => R) : Maybe<R>
{
if (!this.hasv) return Maybe.none;
return new Maybe<R>(func(this.val));
}
/** Turns this maybe into Maybe R or Maybe DefaultVal if there is no value
*/
returnF<R>(func: (v: T) => R, defaultval: R): Maybe<R>
{
if (!this.hasv) return new Maybe(defaultval);
return new Maybe<R>(func(this.val));
}
/** If func is true, return this else return Maybe NONE
*/
ifF(func: (v: T) => boolean): Maybe<T>
{
if (!this.hasv) return Maybe.none;
if (func(this.val))
return this;
else
return Maybe.none;
}
}
}
Upvotes: 2
Views: 6121
Reputation: 437
I would recommend referring to the fantasyland spec when constructing these things. WithF is generally called filter, returnF/withF can be replaced by map/chain. orJust is another method that allows you to provide a default value if your flow returns nothing.
var maybe = new Example.Maybe({ name: "Peter", age: 21 })
.filter(p => p.age === 100)
.map(p => p.name)
.orJust('unknown');
https://github.com/fantasyland/fantasy-land
There is much less to think about when you implement functionality according to the spec. You can also switch to a different data type (such as array/list) fairly easily as the methods will exist on the new type as well.
Upvotes: 3
Reputation: 275937
Your code is good. Only a few minor suggestions.
Prefer
/** True if Maybe contains a non-empty value */
for single line JSDoc comments and
/**
* True if Maybe contains a non-empty value
*/
for multiline ones
There is also a codeplex issue : https://typescript.codeplex.com/workitem/2585 with implementation : https://gist.github.com/khronnuz/1ccec8bea924fe98220e < this one is focusing on iteration where as your's is focusing on continuation
Upvotes: 1