(1) 函数式编程

1 深坑

函数式编程, 最近貌似火了起来, 带跑了一大堆不明所以的吃瓜群众, 涌入了一个以 Haskell 为代表的深坑, 就连守旧的 Java 在 Java8中也加入了 lambda 表达式, 于是乎, 各种Monad, Functor, Applicative等等高大上的名词接踵而至, 搞得人怀疑自己智商是不是已经不适合这个版本了...

2 当然, 这些人不仅仅是为了扯淡!

那么问题来了, 这些东西完全没用吗? 只能说存在即合理, 这群高智商的 PhD 搞出来的东西不仅仅是为了扯淡(还可以发Paper...).
函数式编程的优点呢?

嗯! 翻开百度百科

  1. 代码简洁,开发快速
  2. 接近自然语言,易于理解
  3. 更方便的代码管理
  4. 易于"并发编程"
  5. 代码的热升级
    ...

我 * ! 这么多好处!
代码简洁? 我还学个毛线 Java!
并发编程? 我还学个毛线 Java!
代码热更新? 我还...

撸起袖子就是干!

3 组合(嗯, 黑完 Java 舒服多了)

函数是数学中的概念, 高中数学中, 我们都学过 y = f(x), 自变量x作为输入, y是函数对应的值, 其本质就是从一系列 x 到 y 的映射, 但函数有一个条件, 对于任意一个 x, 都有一个确定唯一的值与其对应, 换句话说就是, 允许多对一, 不允许一对多, 牢记这点相当重要.

举个例子:
比如如下函数
f(x) = x * 2 将 x 的值乘 2 后返回
g(x) = x + 2 将 x 的值 加 2 后返回

如果我们有如下需求

  1. 先要加上2 再 乘 2
    p(x) = f(g(x)) = 2 * (x + 2)
  2. 先乘上2 再加 2
    p(x) = g(f(x)) = 2 + (x * 2)
  3. 在 2 的基础上再 乘上 2
    p(x) = f(g(f(x)))
    我们使用 f(x) 和 g(x) 的组合可以生成很多不同表现形式的函数

如果我们有
函数doClean(room) 代表打扫了房间
函数doTwice(someThing)代表重复做某件事两次
那么 doTwice(doClean(room))就可以代表重复打扫房间两次

假如我们有无限多各种各样的简单函数, 我们是不是能通过组合构建出全世界!

4. 无副作用

数学中的函数还有一个性质, 对于一个固定的输入, 一定会有一个固定的输出, 不管这个函数执行过多少次

比如:
上面例子中, 我们通过不同组合构建出许多不同性质的函数, 但对于某一固定的组合, 如果自变量 x 确定, 那么结果也一定是确定的
p(x) = f(g(f(x))) = 2 * (2 + ( x * 2)) 当 x = 1时, p(1) == 8 永远成立

注意, 数学中的函数式无副作用的, 但常见编程语言中的函数大多是有副作用的, 比如一个 doClean()函数更改了函数外部的一些变量等等, 来表明做了 clean 这件事

4. 抽象

'抽象' 这两个字本来就很抽象...
很多同学对这个词本来就觉得很模糊, WTF! 到底什么是抽象
函数式编程中, 抽象代表着一些列相似动作的总结和归纳
举个例子:
日常生活中, 去日本, 去上海, 去爬山,等一些动作,都有相似性, 我们都可以抽象出来一个公共的动作'去'
所以, 我们就可以总结(抽象)出来

去(日本)
去(上海)
去(爬山)
...

在代码中也是一样的, 我们需要在控制台上打印这个动作被抽象成了print函数, 用来打印
有些同学可能接触过函数式编程中的几个能够装逼的函数map, filter等, 在日常代码中用上几个 mapfilter似乎能让自己的精神升华到另外一个新高度,还可以顺便鄙视下那些习惯用 for循环的同学(哈哈)
其实map就是对 for循环的抽象

// 这段代码就是将数组中的元素加上1之后返回
// // 输出 [2, 3, 4]
for x in [1, 2, 3] {
  var ret = []
  ret.append(x + 1)
  return ret
}
// 这段代码就是将数组中的元素乘5之后返回
// 输出 [5, 10, 15]
for x in [1, 2, 3] {
  var ret = []
  ret.append(x * 5)
  return ret
}

怎么抽象, 其实就是把相似的公共部分提取出来

func map<T, U>(f: (T) -> U, arr: [T]) -> [U] {
  var ret = []
  for x in arr {
    ret.append(f(x))
  }
return ret;
}

// 上面两个例子变成了
map({ $0 + 1 }) // 可以理解成第0个参数 + 1 之后返回
map({ $0 * 5 })

filter 呢?

// 如果符合条件就加进数组返回
func filter<T>(p: (T) -> Bool, arr: [T]) -> [T] {
  var ret = []
  for x in arr {
    if (p(x)) {
       ret.append(x)
    } else {
      continue
    }
  }
  return ret
}

使用这些抽象, 我们可以让我们的代码更易读, 更不易出错

// 被4整除乘2 后能被5整除的第二个整数
integers.filter({ $0 % 4 == 0 }).map({ $0 * 2 }).filter({ $0 % 5 == 0 }).second()

使用 for 循环

// 第一眼你能看出来这段代码是在干嘛吗?
for x in integes {
  var ret = []
  if ret.count == 2 {
    return ret[1]
  }
  if (x % 4 == 0 && (x * 2) % 5 == 0) {
      ret.append(x)
  }
}

5. 敲黑板:

  1. 通过组合简单的函数来构建出复杂的系统, 函数式编程的精髓就在于通过简单的函数来组合成复杂的函数
  2. 对于固定输入输出固定值, 这种性质也可以称作无副作用, 也就是说在函数内部过程不会受函数外部的影响, 也不会影响到函数外部
  3. 抽象是很强大的工具, 它能够让我们简化很多代码, 让代码更简洁, 便于理解, 而且更不易出错
  4. 然而工作中你还是应该继续用 Java, 函数式编程可激发你的脑洞, 但请避免在此越陷越深
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容