首页 > 其他分享 >纯函数、柯里化以及组合函数

纯函数、柯里化以及组合函数

时间:2023-06-27 14:44:17浏览次数:38  
标签:function return 函数 组合 柯里化 console log

纯函数

在程序设计中,若一个函数符合以下条件,那么这个函数被称为纯函数:

  • 此函数在 相同的输入值 时,需产出 相同的输出
  • 函数和输出和输入值以外的其他隐藏信息和状态无关,也和由于 I/O设备产生的外部输出无关。
  • 该函数不能有语义上可观察到的函数副作用,诸如“触发事件”,使输出设备输出,或更改输出值以外物件的内容。

确定的输入一定会产生确定的输出
函数执行的过程中,不会产生任何的副作用

副作用:
在执行一个函数时,除了返回函数数值之外,还对调用函数产生了附加的影响,比如 修改了全局变量,修改参数或者改变外部存储。

柯里化

把接收多个参数的函数,变成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接收余下参数,而且返回结果的新函数的技术。

只传递一部分参数调用函数,并让它返回一个函数去处理剩余的参数的过程就叫做柯里化

function add (x, y, z) {
  return x + y + z
}

const result = add(1, 2, 3)

console.log(result)

// add 函数的柯里化实现

function addC (x) {
  return function (y) {
    return function (z) {
      return x + y + z
    }
  }
}

const resultC = addC(1)(2)(3)
console.log(resultC)

// sum 函数的柯里化简化版本
const addCS = x => {
  return y => {
    return z => {
      return x + y + z
    }
  }
}
console.log(addCS(1)(2)(3))

const addCS2 = x => y => z => x + y + z
console.log(addCS2(1)(2)(3))

柯里化存在的原因(思想?)

  • 在函数式编程中,我们希望一个函数处理的问题尽可能单一,所以将每次传入的参数在单一的函数中进行处理,处理完毕之后在下一个函数中再使用处理后的结果。
  • 并且,柯里化还有助于我们进行逻辑的复用:
function log (date, type, message) {
  console.log(`[${date.getHours()}:${date.getMinutes()}][${type}]:[${message}]`)
}

log(new Date(), 'DEBUG', '查找到轮播图的bug')
log(new Date(), 'DEBUG', '查询菜单的bug')
log(new Date(), 'DEBUG', '查询数据的bug')

// 柯里化使得逻辑复用,减少传参数目

const logC = date => type => message => {
  console.log(`[${date.getHours()}:${date.getMinutes()}][${type}]:[${message}]`)
}

const nowLog = logC(new Date())
nowLog("DEBUG")("测试查找BUG")

const nowAndDebugLog = logC(new Date())('DEBUG')
nowAndDebugLog('查找轮播图BUG')

手写柯里化函数

function add (x, y, z) {
  return this.a + x + y + z
}

function Currying (fn) {
  function curried (...args) {
    if (args.length >= fn.length) {
      // 这里使用 fn.apply 是为了当 f.call({ a: 3 }, 10, 20, 30) 
      // 时将 {a: 3} 作为 fn 的 this
      return fn.apply(this, args)
    } else {
      return function (...args2) {
        return curried.apply(this, [...args, ...args2])
      }
    }
  }
  return curried
}

const f = Currying(add)
console.log(f.call({ a: 3 }, 10, 20, 30)) // 63

组合函数

假设我们现在要对某一个数据进行函数调用,需要依次执行两个函数 fn1、fn2,我们将这两个函数组合起来自动依次调用的过程就称为组合函数。

function double (num) {
  return num * 2
}

function square (num) {
  return num ** 2
}

let count = 10
let result = square(double(count))
console.log(result)

// 组合函数
function composeFn (f, g) {
  return function (count) {
    console.log(g(f(count)))
  }
}

composeFn(double, square)(10)

通用组合函数

function hyCompose (...fns) {
  const length = fns.length
  for (let i = 0; i < length; i++) {
    if (typeof fns[i] !== 'function') {
      throw new TypeError('要求都是函数类型')
    }
  }

  return function (...args) {
    let idx = 0
    let result = length ? fns[idx].apply(this, args) : args
    while (++idx < length) {
      result = fns[idx].call(this, result)
    }
    return result
  }
}

function double (m) {
  return m * 2
}

function square (n) {
  return n ** 2
}

var newFn = hyCompose(double, square)
console.log(newFn(10))

标签:function,return,函数,组合,柯里化,console,log
From: https://www.cnblogs.com/dirtycat/p/17508837.html

相关文章

  • HR-驼峰命名的拆分组合
    说明CamelCase是许多编程语言中常见的一种命名风格。在Java中,方法和变量名通常以小写字母开头,所有后续单词以大写字母开头(例如:startThread)。类的名称遵循相同的模式,只是它们以大写字母开头(例如:BlueCar)。编写一个程序,创建或拆分CamelCase变量、方法和类名。输入格式输入的每一......
  • 实践讲解强化学习之梯度策略、添加基线、优势函数、动作分配合适的分数
    摘要:本文将从实践案例角度为大家解读强化学习中的梯度策略、添加基线(baseline)、优势函数、动作分配合适的分数(credit)。本文分享自华为云社区《强化学习从基础到进阶-案例与实践[5]:梯度策略、添加基线(baseline)、优势函数、动作分配合适的分数(credit)》,作者:汀丶。1策略梯度算法如图......
  • JS(函数、作用域、预解析)
    一函数的概念在JS里面,可能会定义非常多的相同代码或者功能相似的代码,这些代码可能需要大量重复使用。虽然for循环语句也能实现一些简单的重复操作,但是比较具有局限性,此时我们就可以使用JS中的函数。函数:就是封装了一段可被重复调用执行的代码块。通过此代码块可以实现大量......
  • react的函数式组件中使用ref获取到子组件的方法为undefined
    我暂时遇到了两种情况。第一种情况:useImperativeHandle函数写错useImperativeHandle的第二个参数的返回值是作为ref.current的值,但是我写箭头函数写快了,忘记返回值了。useImperativeHandle(ref,()=>{foo},[foo])//错误,这样没有返回值,所以ref.current为undefineduseImp......
  • css颜色变淡和变浅方法收集(模拟sass的darken和lighten函数)
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>Document</title><......
  • 【FreeRTOS复盘】3-FreeRTOS系统的时钟节拍和延时函数
    参考文章1:《FreeRTOS的学习(六)——系统时钟》参考文章2:【FreeRTOS】04系统的时钟节拍和延时函数 原理reeRTOS使用裸机自带的滴答定时器中断,使用其主频或者外部频率作为时钟基准。由于定时器的功能作为FreeRTOS的核心,所以正常情况下必须是一个一直运行着的中断,那么就意味着Fre......
  • 火柴人 VS 数学解析里面的函数
    相关介绍以火柴人的角度解释数学解析里面的函数;......
  • 100 个 pandas 数据分析函数总结 转载
    经过一段时间的整理,本期将分享我认为比较常规的100个实用函数,这些函数大致可以分为六类,分别是统计汇总函数、数据清洗函数、数据筛选、绘图与元素级运算函数、时间序列函数和其他函数。一、统计汇总函数数据分析过程中,必然要做一些数据的统计汇总工作,那么对于这一块的数据运算有哪......
  • 【web开发】PHP其他常用字符串格式及常用加密函数
    前言前两篇文章中我们介绍了日常开发中常用到的字符串格式化函数,本文接着带大家继续了解PHP其他字符串格式化函数及加密函数,字符串的格式化处理函数还有很多,只要是想得到所需要格式化的字符串,都可以调用PHP中的提供的系统内置函数处理即可,很少需要自己定义字符的格式化处理函......
  • R语言用非凸惩罚函数回归(SCAD、MCP)分析前列腺数据|附代码数据
    使用lasso或非凸惩罚拟合线性回归,GLM和Cox回归模型的正则化,特别是_最小_最_大凹_度_惩罚_函数_(MCP)_和光滑切片绝对偏差惩罚(SCAD),以及其他L2惩罚的选项(“弹性网络”)还提供了用于执行交叉验证以及拟合后可视化,摘要,推断和预测的实用程序。我们研究 前列腺数据,它具有8个变量和一......