首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从日常问题到函数式学习

从日常问题到函数式学习
EN

Stack Overflow用户
提问于 2021-01-14 14:53:38
回答 1查看 118关注 0票数 3

我正要学习使用fp-ts的函数式编程,我只是在问自己,怎样才是正确的函数式方法,才能将这样的东西转换成函数式范例:

代码语言:javascript
运行
复制
//OOP:

interface Item {
  name: string;
}

class X {
  private readonly items: { [s:string]: Item[] } = {};

  add(i: Item): Item {
    if(!this.items.hasOwnProperty(i.name))
      this.items[i.name] = [];

    if(this.items[i.name].indexOf(i) < 0)    
      this.items[i.name].push(i);

    return i;
  }
}

所以,我想我应该这样做:

代码语言:javascript
运行
复制
import * as O from 'fp-ts/es6/Option';
import * as E from 'fp-ts/es6/Either';

// using interfaces from above

interface state {
  items: { [s:string]: Item[] }
}

export const createState = (): State => ({ items: {} });


export const add = (s: State, i: Item) => pipe(
  // using IO here?
  E.fromPredicate(
    () => s.hasOwnProperty(i.name),
    () => []
  )
  
    
)

// to use it:

import { createState, add } from './fx';

let state = createState();

// update
state = add(state, {name: 'foo'})

既然add()操作涉及到状态的修改,那么它应该依赖于IO吗?如果add返回一个新的状态对象,那么它是一个纯函数,所以它不需要使用IO?所以我在这里提出的问题可能有点宽泛,但是:这里推荐的技术/模式是什么?

EN

回答 1

Stack Overflow用户

发布于 2021-01-14 20:17:46

既然add()操作涉及到状态的修改,它是否应该依赖IO?

是的,add()不会返回任何内容,但具有有状态的效果,因此它应该返回IO<void>

如果add返回一个新的状态对象,它是一个纯函数,所以它不需要使用IO?

对,是这样。

这里推荐的技术/模式是什么?

函数式程序员通常会不惜一切代价避免使用可变状态。

您正在尝试实现的是一个写时复制的multimap。为此,您不需要来自fp-ts的任何内容。

代码语言:javascript
运行
复制
type MyItem = { name: string };

// we've made the store polymorphic
type MyObj<Item> = { [s: string]: Item[] };

// this is only necessary if you want to expose an implementation-independent api.
export const empty = {};

// i before o, in case we want currying later, o will change more.
const add = <Item>(k: string, v: Item, o: MyObj<Item>) => 
  // abuse the spread operator to get create a new object, and a new array
  ({ ...o, [k]: [v, ...(o[k] || [])] });

// specialization for your item's case
export const addMyItem = (i: MyItem, o: MyObj<MyItem>) => add(i.name, i, o);

然后,您可以执行以下操作:

代码语言:javascript
运行
复制
const a = addMyItem({ name: "test" }, addMyItem({ name: "test" }, empty));
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65714555

复制
相关文章

相似问题

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