首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >函数式编程/光学概念,它使用镜头和横线返回“填充”对象。

函数式编程/光学概念,它使用镜头和横线返回“填充”对象。
EN

Stack Overflow用户
提问于 2020-09-04 23:28:42
回答 1查看 426关注 0票数 3

(Edit I使用的是单片,但如果单ocle-ts是不可能的(因为作者甚至说它只是Scala原版Monocle的一个部分端口),但是如果任何语言的另一个光学包中有什么东西,我愿意将这些想法移植到TypeScript。

假设我有一个助手类型Partial<A>,这样它就代表了一个记录,该记录具有A类型的部分或全部,但没有非成员。(因此,如果A = { foo: number, bar: string }那么Partial<A> = { foo?: number, bar?: string }) (编辑,这是类型记录的内置部分实用程序类型)。

我首先

代码语言:javascript
复制
interface Parent {
  xs: Child[]
}

interface PartialParent {
  partialxs: Partial<Child>[]
}

declare function fillInTheGaps(x: Partial<Child>):Child

假设我已经组成了一个透镜和遍历组合(composedTraversal),这样它就可以聚焦于来自PartialStatepartialxs,然后作为一个数组遍历它。这将是一个Traversal<PartialState, Partial<Child>>

另外,假设我有一个declare const fn = (x:Partial<Child>):Partial<Child>,那么我可以将fn应用于所有composedTraversal.modify(fn)(partialState)儿童,这将产生一个新的PartialState,并将fn应用于所有partialxs

是否有什么概念可以让我“扩大”或“将”这个遍历变成不同的东西,这样我就可以组合镜头和遍历,并使用fillInTheGaps,这样我就可以传入PartialState并返回一个State

忽略了我的语法是TypeScript,我添加了monocle-scala标记,因为如果这个概念存在的话,我想它就在Monocle库中,我可以将这些知识转换到我正在使用的库中。

编辑引发这个问题的问题是,我在一个Redux应用程序中有一个表单输入,其中用户输入数据,但大多数不是必需的。输入在编译时不知道(它们是从RESTful API查询重试的),所以我不能将模型表示为

代码语言:javascript
复制
interface Model {
  foo?: string[]
  bar?: string[]
}

相反,它被表示为

代码语言:javascript
复制
interface Model {
  [index:string]: string[]
}

我还可以从RESTful服务器获取默认模型。因此,我将它们建模为Parent (来自服务器的内容)和Partial<Parent> (代表用户在应用程序中的输入)。

在进行一些计算之前,我需要折叠丢失的道具的默认值。这是上面引用的我的fillInTheGaps函数。

我们的愿望是通过代码中的类型来实现这一点,而且,因为我已经编写了很多光学软件,所以可以重用其中的一些内容。实际上,我已经编写了一个镜头和遍历来对这些数据执行其他操作。myLens.compose(myTraversal).modify(fn)接受一个Partial<State>并返回一个Partial<State>,但是我希望将它们组合成一个函数,该函数接受部分并返回整个函数。

很明显,我可以直接写const filler: (Partial<State>):State = myLens.compose(myTraversal).modify(fillInTheGaps),然后在上面加一个//@ts-ignore,知道它能用,但这看起来,呃,很脆弱。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-09-08 23:25:18

我想,你可能想要一个PTraversal

一个Traversal<S, A>说,“如果我有一个函数A => A,我可以使用modify获得一个函数S => S,它使用原始函数来修改出现在S中的所有A”。

相比之下,PTraversal<S, T, A, B>说,“如果我有一个函数A => B,我可以使用modify获得一个函数S => T",这会将S中的所有A转换为B,从而生成一个T

PTraversal的类型参数是:

  • SPTraversal的来源
  • T -- PTraversal的“修改”源
  • A -- PTraversal的目标
  • B -- PTraversal的“修改”目标

PTraversal是有用的,因为它们允许您编写如下内容:

代码语言:javascript
复制
PTraversal<Array<A>, Array<B>, A, B>

允许您在更改元素类型的同时遍历Array

在您的具体案例中,您提到了具有两个功能:

代码语言:javascript
复制
declare function fillInTheGaps(x: Partial<Child>):Child
declare function fn(x: Partial<Child>):Partial<Child>

这些功能可以一起组成,以产生一个单一的功能:

代码语言:javascript
复制
function transformAndFill(x: Partial<Child>): Child {
   return fillInTheGaps(fn(x)); 
}

然后,您需要编写一个PTraversal<PartialState, State, Partial<Child>, Child>

这将支持使用Lens进行组合,从而以与Traversal相同的方式生成新的PTraversal

这应该是可行的,我认为从您的问题中可以看出,如果您可以将PartialState中的每个PartialState转换为Child,那么您应该能够生成一个State

PTraversal存在于Monocle ( Scala库)中,但不幸的是,它看起来不像是将其转换为monocle-ts:因此不幸的是,您必须编写相当多的光学库代码才能支持这一点。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63749061

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档