Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript fp ts:我该怎么做;“向上拉”;是否将嵌套的`other`/`taskother`添加到外部类型?_Typescript_Fp Ts - Fatal编程技术网

Typescript fp ts:我该怎么做;“向上拉”;是否将嵌套的`other`/`taskother`添加到外部类型?

Typescript fp ts:我该怎么做;“向上拉”;是否将嵌套的`other`/`taskother`添加到外部类型?,typescript,fp-ts,Typescript,Fp Ts,我正在学习一些fp-ts。要创建我遇到的问题的样式化版本,假设我想要创建一个不存在的表,所以我必须查询数据库:一个容易出错的异步操作。如果该表不存在,我想创建它:另一个容易出错的异步操作。进一步假设错误类型都是字符串(尽管我还想知道如何在需要时创建union错误类型),并且成功创建时返回的值是数字ID 简言之,查看表是否存在,如果不存在,则在创建过程中可能会出现错误。关键是我希望这两个错误都反映在最外层的类型中:atask或。问题是我不知道如何避免获得任务。也就是说,我不知道如何将选项中的错误向

我正在学习一些
fp-ts
。要创建我遇到的问题的样式化版本,假设我想要创建一个不存在的表,所以我必须查询数据库:一个容易出错的异步操作。如果该表不存在,我想创建它:另一个容易出错的异步操作。进一步假设错误类型都是字符串(尽管我还想知道如何在需要时创建union错误类型),并且成功创建时返回的值是数字ID

简言之,查看表是否存在,如果不存在,则在创建过程中可能会出现错误。关键是我希望这两个错误都反映在最外层的类型中:a
task或
。问题是我不知道如何避免获得
任务。也就是说,我不知道如何将
选项中的错误向上拉,并将其合并到最外层的错误中

(也许这涉及序列或可遍历项?我仍在学习这些。)

关于某些代码:

从“fp ts”导入{task或作为TE,选项作为O};
从“fp ts/lib/function”导入{pipe};
//tableExists:()=>TE.task
//createTable:()=>TE.tasktable
//我希望这能代表两种可能的错误。当前存在类型错误。
//------------------------------------VV
常量示例=():TE.taskOrther=>{
回流管(
tableExists(),
//如何将可能的“left”向上拉至最外层类型?
//---------------------------------------VVVVVV
TE.map((存在)=>(存在?O.none:O.some(createTable())
);
};

我相信我已经解决了这个问题,当然欢迎任何更正

我认为我需要将
选项
向下“推”到嵌套的
任务
中,而不是将
任务
选项
中向上“拉”,以便嵌套将
任务
的层彼此相邻,允许通过
将它们展平

const-example=():TE.taskOrther=>
烟斗(
tableExists(),
TE.链((存在)=>
存在
?测试结果(无)
:管道(
createTable(),
TE.地图(O.of)
)
)
);

如果错误类型不同,我会怎么做的附带问题似乎也由此代码处理,除了
TE.chainW
替换
TE.chain
似乎是您自己解决的:)如果有帮助,我已经将这个示例实现为一个有区别的联合,这样您就可以很容易地识别调用
example
时发生的错误

import * as TE from 'fp-ts/lib/TaskEither'
import * as O from 'fp-ts/lib/Option'
import { pipe } from "fp-ts/lib/function";

declare const tableExists: () => TE.TaskEither<string, boolean>
declare const createTable: () => TE.TaskEither<string, number>

// Discriminated union so you can easily identify which error it is
type ExampleErr = { tag: "TableExistsError", error: unknown } | { tag: "CreateTableError", error: unknown }

const example = (): TE.TaskEither<ExampleErr, O.Option<number>> => {
  return pipe(
    tableExists(),
    TE.mapLeft(error => ({ tag: "TableExistsError" as const, error })),
    TE.chainW(exists => exists ?
      TE.right(O.none) :
      pipe(
        createTable(),
        TE.mapLeft(error => ({ tag: "CreateTableError" as const, error })),
        TE.map(O.some)
      )
    )
  );
};
import*as TE from'fp ts/lib/taskother'
从“fp ts/lib/Option”以O形式导入*
从“fp ts/lib/function”导入{pipe};
declare const tableExists:()=>TE.task
声明const createTable:()=>TE.tasktable
//有区别的联合,因此您可以轻松确定它是哪个错误
键入ExampleErr={tag:“TableExistError”,错误:未知}{tag:“CreateTableError”,错误:未知}
常量示例=():TE.taskOrther=>{
回流管(
tableExists(),
mapLeft(error=>({tag:“TableExistError”作为常量,error})),
TE.chainW(exists=>exists?
TE.右(无):
烟斗(
createTable(),
mapLeft(error=>({tag:“CreateTableError”作为常量,error})),
特图(O.some)
)
)
);
};
如果
table存在
createTable
中的错误类型不同,您已正确识别需要使用
chainW
fp ts
中函数末尾的
W
表示“加宽”,通常允许类型加宽到两种类型的并集。对于
taskorth
chainW
,这意味着错误类型将成为两种
taskorth
类型的并集(进入
chainW
的类型和在其中返回的类型)


理解何时使用
map
以及何时使用
chain
是一个基本概念,这对于理解好非常重要
map
允许您修改结构中的值,这是
a->B
中的一个简单函数<代码>链
允许您根据第一个效果执行另一个效果-因此您必须返回一个值,该值与处理的效果相同。在本例中,您使用的是
tasktory
,因此传递给
chain
的函数也需要是
A->tasktory
类型(其中
createTable
是,但是您还需要手动处理表已经存在的情况,并使用
TE.right(O.none)在那里构建tasktory)
TE.of(O.none)

有道理,谢谢!我知道有点生锈,在这里看到相同或相似的概念很有趣(
map
和_-then
/
chain
;等等)。虽然我还没有完全掌握单子、函子、应用程序等的理论,但我通过这些语言/库结构将这些理论付诸实践,从实践的角度理解了它们的价值和用途。很酷的东西!