如何使用不变性和函数式编程实践构造具有多种可能长度的数组?

Luk*_*ams 0 haskell functional-programming immutability typescript elm

我们正在将我们的命令性大脑转变为功能最强大的范例.这个功能给我带来了麻烦.我想要构造的阵列,要么包括两对对或三对,根据条件(是否refreshTokennull).如何使用FP范例干净利落地完成这项工作?当然,对于命令式代码和变异,我只是有条件地.push()将额外的值放到最后看起来非常干净.

这是"本地突变是否正确"FP警告的一个例子?

(我们ReadonlyArray在TypeScript中使用强制实现不变性,这使得它更难看.)

const itemsToSet = [
    [JWT_KEY, jwt],
    [JWT_EXPIRES_KEY, tokenExpireDate.toString()],
    [REFRESH_TOKEN_KEY, refreshToken /*could be null*/]]
    .filter(item => item[1] != null) as ReadonlyArray<ReadonlyArray<string>>;

AsyncStorage.multiSet(itemsToSet.map(roArray => [...roArray]));
Run Code Online (Sandbox Code Playgroud)

Mar*_*ann 5

itemsToSetOP中给出的错误是什么?它看起来很实用,但可能是因为我对TypeScript缺乏了解.

在Haskell中,没有null,但是如果我们使用Maybe第二个元素,我认为itemsToSet可以转换为:

itemsToSet :: [(String, String)]
itemsToSet = foldr folder [] values
  where
    values = [
      (jwt_key, jwt),
      (jwt_expires_key, tokenExpireDate),
      (refresh_token_key, refreshToken)]
    folder (key, Just value) acc = (key, value) : acc
    folder _ acc = acc
Run Code Online (Sandbox Code Playgroud)

这里jwt,tokenExpireDaterefreshToken是所有类型的Maybe String.

itemsToSet执行右折叠values,模式匹配的Maye String对元件Just和(隐含地)Nothing.如果它是一个Just值,它将该(key, value)对与累加器相关联acc.如果没有,folder只需返回acc.

foldrvalues从右到左遍历列表,在访问每个元素时构建累加器.初始累加器值是空列表[].

在函数式编程中不需要"局部变异".通常,您可以通过使用递归和引入累加器值来将"局部变异"重构为正确的函数样式.

虽然foldr是内置函数,但您可以使用递归自己实现它.

  • `itemsToSet = catMaybes $ fmap sequenceA values`;) (3认同)
  • 哈哈!抱歉.不打算在你身上投下脑弹!简而言之:`sequenceA ::(Applicative f,Traversable t)=> t(fa) - > f(ta)`是转置两个构造函数的通用工具.这里`f~ Maybe`和`t~(,)String`,所以**`sequenceA ::(String,Maybe String) - > Maybe(String,String)`**.如果我们有`t~ []`,`sequenceA :: Applicative f => [fa] - > f [a]`将序列_many_效果产生一个结果列表.这里只有_one_效果:"容器"类型是元组,它"包含"它的第二个元素.然后`catMaybes`就过滤了`Nothing`s.希望能解释一下!:) (2认同)
  • 是的,特别是`(,)x`的`可折叠`/`可遍历`实例多年来证明是非常有争议的.我可以看到论点的两个方面:它们经常会导致学习者绊倒,但是一旦你熟悉了"可折叠"和"可穿越",它们就会变得有用. (2认同)