首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >访问嵌套属性的泛型类型

访问嵌套属性的泛型类型
EN

Stack Overflow用户
提问于 2019-08-30 23:41:18
回答 1查看 60关注 0票数 1

我试图在TypeScript中实现一个monad,特别是这个例子中的join方法。

有待解决的问题如下:

代码语言:javascript
复制
const mm3 = new Maybe(new Maybe(3)); // Maybe<Maybe<number>>
const m3 = mm3.join();               // Maybe<number>

join方法不嵌套两个Maybe,但是在调用join时,Maybe可以处于三种状态。预期产出如下所示。

代码语言:javascript
复制
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()

含糊不清地试图实施..。

代码语言:javascript
复制
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是否有能力或是否需要高类

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-31 01:23:25

实现Monad的各个实例(如Maybe )是非常简单的,只要您不想表示Monad本身,这真的需要高类.正如你所知道的,TypeScript没有直接的支持。( 有些人似乎有一些间接的想出支持,但是没有什么足够干净的东西我想在这里推荐)

如果您想强键入Maybe.prototype.join()而不担心代码中的"Monad“,我建议使用泛型参数,如下所示:

代码语言:javascript
复制
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属性。

让我们来测试一下:

代码语言:javascript
复制
const mm3 = new Maybe(new Maybe(3)); // Maybe<Maybe<number>>
const m3 = mm3.join(); // Maybe<number>

这正是你想要看到的。还请注意,调用m3.join()是编译时错误:

代码语言:javascript
复制
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。

好吧,希望这能帮上忙,祝你好运!

链接到代码

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57734154

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档