我有以下代码:
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)是否有更好的方法来组合功能?
答案 0 :(得分:0)
此复杂性是由于需要在任务和任务之间进行切换,并且两种类型之间没有自然的转换。为什么不使用现有的taksEither类型? fp ts的文档非常差,所以我还是使用了另一个库的任务(来自fluture js)重写了您的代码
相反,这是使用fluturejs(本质上是任务+)之一的样子
app-db
我无法扫描文档并弄清楚这些功能在fp-ts的实现中被称为什么,但是我确定它们都存在。 Flutures并行函数获取一个Futures列表,并返回该列表的Future,此行为本质上是连续的,应该存在于fp-ts的任务中,因为它必须在monads上实现
还有,如果您重新设计了repo类并使它的方法返回任务,那么您将进一步简化代码。