[英]Task, Lift and complex monads in FP-TS
I have the following code: 我有以下代码:
import { Task, task } from "fp-ts/lib/Task"
import { Either, left, right } from "fp-ts/lib/Either"
import { curry } from "fp-ts/lib/function"
import { liftA2 } from "fp-ts/lib/Apply"
import { Repo } from "./repo"
const buildPerson = curry((name: string, age: number): Either<Error, any> => {
if (name !== undefined && age !== undefined) {
return right({ name, age })
} else {
return left(Error("Missing parameter"))
}
})
const validatePerson = (person: any): Either<Error, any> => {
if ( person.age < 18) {
return left(Error("Too Young"))
} else {
return right(person)
}
}
const getNameFromRepo = (repo: Repo): Task<string> => {
return new Task(
() => repo.getName()
)
}
const getAgeFromRepo = (repo: Repo): Task<number> => {
return new Task(
() => repo.getAge()
)
}
const savePerson = curry((person:any, repo: Repo): Task<void> => {
return new Task(
() => {
console.log(person)
return repo.setPerson(person)
}
)
})
const hello = async () => {
const repo = new Repo()
await liftA2(task)(buildPerson)(getNameFromRepo(repo))(getAgeFromRepo(repo))
.map(
(e) => e.chain(
(p) => validatePerson(p)
)
)
.map(
(e) => e.fold(
(l) => console.log(l),
(r) => savePerson(r)
)
)
.run()
}
hello()
1) savePerson function doesn't get run, return type however is Promise 1)savePerson函数不会运行,但是返回类型是Promise
2) Fp-Ts library indicates that liftA2 type is deprecated and I should use sequenceT instead. 2)Fp-Ts库指示不建议使用liftA2类型,而应该使用sequenceT。 However from the signature it's not clear how sequenceT would apply to the parameters of buildPerson like liftA2 does
但是从签名中还不清楚,sequenceT将如何像liftA2一样应用于buildPerson的参数
3) Is there a better way to compose the functions? 3)有没有更好的方法来组合功能?
This complication is caused by needing to go between either and task and there not being a natural transformation between the two types. 这种复杂性是由于需要在任务和任务之间切换而导致的,并且两种类型之间没有自然的转换。 Why not use the existing taksEither type?
为什么不使用现有的taksEither类型? fp ts has very poor docs so I rewrote your code using a different library's taskeither (from fluture js)
fp ts的文档非常差,所以我还是使用其他库的任务重写了代码(来自fluture js)
Instead heres how this would look using fluturejs (essentially task + either) 相反,这是使用fluturejs的样子(本质上是task +任一个)
import * as Future from 'fluture';
const buildPerson = (name, age) =>
name !== undefined && age !== undefined
? Future.of({ name, age })
: Future.reject(Error("Missing parameter"));
const validatePerson = ({ name, age }) =>
age < 18
? Future.reject(Error("Too Young"))
: Future.of({ name, age });
const getNameFromRepo = (repo: Repo) => {
return Future.Future((reject, resolve) =>
resolve(repo.getName()));
}
const getAgeFromRepo = (repo: Repo) => {
return Future.Future((reject, resolve) =>
resolve(repo.getAge()));
}
const savePerson = (repo: Repo) => (person) => {
return Future.Future((reject, resolve) =>
resolve(repo.setPerson(person)));
}
const hello = (repo: Repo) =>
Future.parallel(1, [
getNameFromRepo(repo),
getAgeFromRepo(repo),
])
.chain(([name, age]) => buildPerson(name, age))
.chain(validatePerson)
.chain(savePerson(repo))
.fork(
(err) => console.warn('err', err),
() => console.log('it worked!'),
);
hello(new Repo());
I wasnt able to scan the docs and figure out what these functions are called in fp-ts's implementation but Im sure they all exist. 我无法扫描文档并找出这些功能在fp-ts的实现中被称为什么,但我确定它们都存在。 Flutures parallel function takes a list of Futures and returns a future of a list, this behavior is essentially concat and should exist in fp-ts's taskeither because its required to be implemented on monads
Flutures并行函数获取一个Futures列表并返回一个list的Future,此行为本质上是concat,应该在fp-ts的任务中存在,因为它必须在monads上实现
Futhermore, if you redesigned the repo class and have its methods return taskeithers, you will further simplify your code. 此外,如果您重新设计了repo类并使其方法返回task,那么您将进一步简化代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.