(cljs/run-at (JSVM. :all) "一起实现柯里化")
前言
习惯了Ramda.js就会潜意识地认为函数均已柯里化,然后就可以随心所欲的用函数生成函数,或者使用compose组合多个函数来生成一个新函数。如下
const f = a => b => a + b
const g = c => d => c - d
const compose = f => g => x => f(g(x))
const add1 = f(1)
add1(2) // 返回3
const addThenMinus = compose(g(2), f(1))
addThenMinus(3) // 返回-2
ES6的arrow function让我们轻易写出柯里化的函数(当然使用Ramda.js会更轻松),若换成ES5就蛋痛很多了。而不幸的是cljs采纳和js一样能够接受可变参数的函数特性,这使得其必须抛弃如haskell函数自动柯里化的特性。若用cljs实现上述代码将会如此地丑陋
(defn f [a]
(fn [b] (+ a b)))
(defn g [c]
(fn [d] (- c d)))
(def add1 (f 1))
那么要如何才能在cljs中优美地实现柯里化呢?答案是两步走:
- 实现Ramda.js中
R.curry函数的cljs版 - 借助curry函数实现macro
实现curry函数
;; 定义
(defn curry
[f n & args]
(fn [& more]
(let [a (vec (concat args more))]
(if (> n (count a))
(apply curry (reduce conj [f n] a))
(apply f (take n a))))))
;; 使用
(defn f [a b]
(+ a b))
(def fc (curry f 2))
(def add1 (fc 1))
实现defnc宏
;; 定义
(defmacro defnc [name args & body]
{:pre [(not-any? #{\&} args)]}
(let [n (count args)]
`(def ~name
(curry
(fn ~args ~@body)
~n))))
;; 使用
(defnc f [a b]
(+ a b))
(def add1 (f 1))
总结
cljs中的macro让我们可以灵活扩展语言特性,真是越用越酸爽啊!
尊重原创,转载请注明来自:http://www.cnblogs.com/fsjohnhuang/p/7103601.html _肥仔John
(cljs/run-at (JSVM. :all) "一起实现柯里化")的更多相关文章
- JS的防抖,节流,柯里化和反柯里化
今天我们来搞一搞节流,防抖,柯里化和反柯里化吧,是不是一看这词就觉得哎哟wc,有点高大上啊.事实上,我们可以在不经意间用过他们但是你却不知道他们叫什么,没关系,相信看了今天的文章你会有一些收获的 节流 ...
- Scala学习笔记——简化代码、柯里化、继承、特质
1.简化代码 package com.scala.first import java.io.File import javax.management.Query /** * Created by co ...
- Scala 基础(十二):Scala 函数式编程(四)高级(二)参数(类型)推断、闭包(closure)、函数柯里化(curry)、控制抽象
1 参数(类型)推断 参数推断省去类型信息(在某些情况下[需要有应用场景],参数类型是可以推断出来的,如list=(1,2,3) list.map() map中函数参数类型是可以推断的),同时也可以 ...
- JS 函数的柯里化与反柯里化
===================================== 函数的柯里化与反柯里化 ===================================== [这是一篇比较久之前的总 ...
- JS - 柯里化
一:what's this? 柯里化: 是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术.其实,柯里化就是用闭包原理实现函数 ...
- JAVAScript柯里化、部分应用参数终极理解
一.柯里化 在定义柯里化.部分应用参数的概念前,首先必须对闭包有深入的了解和定义,闭包一句话说清楚:函数返回值为函数. 柯里化的定义:将多参函数分解为按步骤接受单个参数的函数,如下代码: var mo ...
- 【转载】JS中bind方法与函数柯里化
原生bind方法 不同于jQuery中的bind方法只是简单的绑定事件函数,原生js中bind()方法略复杂,该方法上在ES5中被引入,大概就是IE9+等现代浏览器都支持了(有关ES5各项特性的支持情 ...
- 前端开发者进阶之函数柯里化Currying
穆乙:http://www.cnblogs.com/pigtail/p/3447660.html 在计算机科学中,柯里化(英语:Currying),又译为卡瑞化或加里化,是把接受多个参数的函数变换成接 ...
- javascript中利用柯里化函数实现bind方法
柯理化函数思想:一个js预先处理的思想:利用函数执行可以形成一个不销毁的作用域的原理,把需要预先处理的内容都储存在这个不销毁的作用域中,并且返回一个小函数,以后我们执行的都是小函数,在小函数中把之前预 ...
随机推荐
- SSH协议(转载)
一. SSH是什么? SSH的全称是Secure Shell, 是一种"用来在不安全的网络上安全地运行网络服务的一种加密网络协议". 简单说,SSH是一种网络协议,用于计算机之间的 ...
- 面试(2)-java-se-HashSet和TreeSet
Set是java中一个不包含重复元素的collection.更正式地说,set 不包含满足 e1.equals(e2) 的元素对 e1 和 e2,并且最多包含一个 null 元素.正如其名称所暗示的, ...
- Handling Class Imbalance with R and Caret - An Introduction
When faced with classification tasks in the real world, it can be challenging to deal with an outcom ...
- 如何通过JS实现简单抖动效果
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- [HDU1001] Sum Problem
Problem Description Hey, welcome to HDOJ(Hangzhou Dianzi University Online Judge). In this problem, ...
- xampp教程(一):xampp下载,安装,配置,运行PHP的web项目
本来没有想着弄PHP,但是有同学叫我帮忙启动一下一个PHP写的后台.着实需要去学习一下. 想着安装xampp软件,一个集合了多个服务器,多个数据库,多个后台语言的管理软件. 一.xampp下载 二.安 ...
- characterEncodingFilter作用
package com.demo.test; import java.io.IOException; import javax.servlet.Filter; import javax.servlet ...
- 平时常用的一些java方法,请留意
平时常用的一些java方法,请留意. package com.util; import java.io.BufferedInputStream; import java.io.BufferedWrit ...
- js 排序:sort()方法、冒泡排序、二分法排序。
js中的排序,这里介绍三种,sort()方法.冒泡排序.二分法排序. 1.sort方法 写法: 数组.sort(); 返回排好序的数组,如果数组里是数字,则由小到大,如果是字符串,就按照第一个字符的 ...
- Coursera 机器学习笔记(八)
主要为第十周内容:大规模机器学习.案例.总结 (一)随机梯度下降法 如果有一个大规模的训练集,普通的批量梯度下降法需要计算整个训练集的误差的平方和,如果学习方法需要迭代20次,这已经是非常大的计算代价 ...