我有以下代码:
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函数未运行,但返回类型为Promise
2) Fp-Ts库指示liftA2类型已弃用,我应该使用sequenceT。但是,从签名来看,并不清楚sequenceT如何像liftA2那样应用于buildPerson的参数
3)有没有更好的组合函数的方法?
发布于 2019-07-11 15:49:09
这种复杂性是由于需要在和任务之间进行转换,并且这两种类型之间没有自然的转换。为什么不使用现有的taksEither类型?fp ts的文档非常糟糕,所以我用另一个库的taskeither (来自fluture js)重写了你的代码。
相反,这里是使用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());我无法浏览文档并弄清楚这些函数在fp-ts的实现中被调用了什么,但我确信它们都存在。Flutures并行函数接受一个Futures列表并返回一个列表的未来,这个行为本质上是连接的,应该存在于fp-ts的taskeither中,因为它需要在monad上实现
此外,如果您重新设计了repo类,并让它的方法返回taskeither,您将进一步简化您的代码。
https://stackoverflow.com/questions/56202990
复制相似问题