我试图在TypeScript中实现一个monad,特别是这个例子中的join方法。
有待解决的问题如下:
const mm3 = new Maybe(new Maybe(3)); // Maybe<Maybe<number>>
const m3 = mm3.join(); // Maybe<number>join方法不嵌套两个Maybe,但是在调用join时,Maybe可以处于三种状态。预期产出如下所示。
new Maybe(new Maybe(3)).join(); // Maybe<number>(3)
new Maybe<number>(null).join(); // Maybe<number>(null)
new Maybe(3).join(); // 3 - Not the normal use-case for join()含糊不清地试图实施..。
interface IMonad<T> {
join(): T; // Works for cases #1 and #3 above but
// really I want to express that we're
// returning an IMonad<number> in the examples.
// Or even better, a Maybe<number> in the case of Maybe
}
class Maybe<T> implements IMonad<T> {
private value: T | null;
public constructor(value: T | null | undefined) {
this.value = (value === null || value === undefined) ? null : value;
}
public join(): T {
if (this.value === null) {
return Maybe.of<??>(null); // 'number' in these examples
} else {
return this.value;
}
}
}我很想弄清楚这是怎么回事。有什么想法吗?TypeScript是否有能力或是否需要高类?
发布于 2019-08-31 01:23:25
实现Monad的各个实例(如Maybe )是非常简单的,只要您不想表示Monad本身,这真的需要高类.正如你所知道的,TypeScript没有直接的支持。( 有些人似乎有一些间接的想出支持,但是没有什么足够干净的东西我想在这里推荐)
如果您想强键入Maybe.prototype.join()而不担心代码中的"Monad“,我建议使用泛型参数,如下所示:
class Maybe<T> {
constructor(public value?: T) {}
join<U>(this: Maybe<Maybe<U>>) { // this parameter
return new Maybe(
typeof this.value === "undefined" ? undefined : this.value.value
);
}
}(在这里,我只将undefined作为"nothing“值处理;如果需要,可以添加对null的支持)
this参数要求将其作为匹配类型对象的方法调用。因此,通过让join()的this be Maybe<Maybe<U>>用于某些通用的U,我们保证this.value,如果不是undefined,它本身就有一个value属性。
让我们来测试一下:
const mm3 = new Maybe(new Maybe(3)); // Maybe<Maybe<number>>
const m3 = mm3.join(); // Maybe<number>这正是你想要看到的。还请注意,调用m3.join()是编译时错误:
const oops = m3.join(); // error!
/* The 'this' context of type 'Maybe<number>' is not assignable to method's
'this' of type 'Maybe<Maybe<unknown>>'. Type 'number' is not assignable
to type 'Maybe<unknown>'. */在我看来,这似乎是正确的行为;您不能join()一个非嵌套的monad。
好吧,希望这能帮上忙,祝你好运!
链接到代码
https://stackoverflow.com/questions/57734154
复制相似问题