我对函数式编程(尤其是$path = public_path("2020/March/tes.pdf");
库)很陌生。
我的问题包括两个部分:
fp-ts
转变为Task
,反之亦然,我们应该如何处理呢?我们应该始终保持一种状态还是应该改变随着链条的延续?例如,假设我们有几个函数,并且希望将它们组合如下,我知道此示例可能不太实用,但可以达到目的。
IO
答案 0 :(得分:3)
1。)将Monad从一种类型转变为另一种类型,我们该如何处理?我们应该始终保持一种状态,还是应该随着链条的不断发展而改变?
您希望某种(natural) transformation从IO
切换到Task
/ TaskEither
。相反,对于我来说这没有意义,因为异步效果无法转换为同步效果。
chain
将preserve the structure 。因此,getPage
中的IO.chain(getPage)
需要签名number -> IO<whatever>
。您可以改为使用map
添加一个额外的嵌套层,例如:
pipe(getRnd(2, 4), IO.map(getPage)); // I.IO<TE.TaskEither<Error, string>>
通常,没有对与错的方法,仅取决于目的。注意,嵌套的数据类型越多,处理内部值的难度就越大。具有代数结构的函数式编程的一部分是为了避免在源头进行不必要的嵌套。
在您的情况下,将所有内容统一在统一的TaskEither
中确实是有意义的-类型IO<TaskEither<...>>
与TaskEither<...>
并没有任何优势。
2。)如何简单地使打字稿跟随从一个到另一个的这些类型更改?
您可以使用TaskEither.rightIO
将IO
转换为TaskEither
(CodeSandbox):
import { taskEither as TE, io as I, option as O, pipeable as P, either as E } from "fp-ts";
declare function log<T>(t: T): I.IO<T>;
const getPageLinks = P.pipe(
getRnd(2, 4),
TE.rightIO,
TE.chain(getPage),
TE.map(getLinks),
TE.chain(v => TE.rightIO(log(v)))
); // TE.TaskEither<Error, O.Option<string[]>>
这也是可行的,因为TS使用结构化类型(但我建议使用前者):
const getPageLinks2 = P.pipe(
getRnd(2, 4),
I.chain(getPage), // this also works
I.map(v => v.then(vv => E.either.map(vv, getLinks))),
I.chain(log)
); // I.IO<Promise<E.Either<Error, O.Option<string[]>>>>