Может быть, монада в TypeScript

Я играю с монадой Maybe в TypeScript. Мое понимание концепций невелико, поэтому я буду рад любым отзывам или предложениям. Есть множество примеров JS, но я ищу что-то более строго типизированное.

Использование будет примерно таким:

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

Потому что if/with/return зарезервированные слова, я только что добавил F в конец.

Пока у меня есть:

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;
        }
    }
}

person user826840    schedule 14.07.2014    source источник


Ответы (2)


Ваш код хорош. Только несколько незначительных предложений.

JS-документ

Предпочитать

/** True if Maybe contains a non-empty value */

для однострочных комментариев JSDoc и

  /** 
    * True if Maybe contains a non-empty value
    */

для многострочных

Другие реализации

Также существует проблема с кодеплексом: https://typescript.codeplex.com/workitem/2585 с реализацией: https://gist.github.com/khronnuz/1ccec8bea924fe98220e ‹ это сосредоточившись на итерации, где ваш фокусируется на продолжении

person basarat    schedule 14.07.2014

Я бы порекомендовал обращаться к спецификации страны фантазий при конструировании этих вещей. WithF обычно называется filter, returnF/withF можно заменить на map/chain. orJust — это еще один метод, который позволяет указать значение по умолчанию, если ваш поток ничего не возвращает.

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

Когда вы реализуете функциональность в соответствии со спецификацией, о ней нужно думать гораздо меньше. Вы также можете довольно легко переключиться на другой тип данных (например, массив/список), так как методы будут существовать и в новом типе.

person Alfred Young    schedule 11.07.2019
comment
Глядя на исходные имена функций, я не был так уверен, что они делают, поэтому мне пришлось прочитать их реализацию, чтобы понять их работу. С вашим кодом очень ясно, что они делают, даже не глядя на их реализацию. Хорошая работа! - person benshabatnoam; 11.07.2019