首页 > 解决方案 > 使用自己的 Monad 时 Ramda 链的打字稿类型

问题描述

我试图更多地了解打字稿中的函数式编程。所以作为练习,我写了一个Reader单子。但是我在使用 ramda 时遇到了类型问题。不知道如何理解我收到的错误消息。希望有人能指出我正确的方向。

下面是我的测试之一。我有两个函数依赖于来自 Reader 的值,我想通过管道传输它们。所以我必须将链用于第二个功能。如果我使用我自己的Reader.chain(stars),我不会收到任何错误,但是当我尝试 ramda 时,R.chain(stars)我会从 typescript 收到错误,但程序可以工作。

const hello = (name: string) =>
    Reader.asks(({ greeting }: { greeting: string }) => `${ greeting } ${ name }`)
const stars = (s: string) =>
    Reader.asks(({ stars }: { stars: boolean }) => `${ stars && '**' }${ s }`)
const program = R.pipe(
    hello,
    R.chain(stars),
)
const result = program('Alice').run({ greeting: 'Hello', stars: true })
expect(result).toEqual('**Hello Alice')

线路错误信息R.chain(stars),

No overload matches this call.
  The last overload gave the following error.
    Argument of type 'unknown[]' is not assignable to parameter of type '(x: Reader<{ greeting: string; }, string>) => unknown'.
      Type 'unknown[]' provides no match for the signature '(x: Reader<{ greeting: string; }, string>): unknown'.

我的 Reader 实现的代码,最相关的是链方法,我删除了不相关的方法:

class Reader<Context, Result> {
    constructor(private _exec: (context: Context) => Result){
    }

    public static asks<E, T>(fn: (context: E) => T): Reader<E, T>{
        return new Reader(fn)
    }

    public run(context: Context): Result{
        return this._exec(context)
    }

    public chain<A, B>(fn: (a: Result) => Reader<B, A>): Reader<Context & B, A>{
        return new Reader(context => fn(this._exec(context)).run(context))
    }

    public static chain = <Context, Result, A, B>(fn: (a: Result) => Reader<B, A>) =>
        (reader: Reader<Context, Result>): Reader<Context & B, A> =>
            reader.chain(fn)
}

我不明白错误消息,希望有人知道如何修复它或者我可以在哪里阅读更多关于它的信息。

标签: typescriptfunctional-programmingramda.js

解决方案


推荐阅读