monad 学习笔记

functor (实现了map的数据类型) & monad (实现了flatMap的数据类型)

就以optional 的map 和 flatMap 来说

public func map<U>(@noescape f: (Wrapped) throws -> U) rethrows -> U?  简化下  map:(f(x)) ->U?

public func flatMap<U>(@noescape f: (Wrapped) throws -> U?) rethrows -> U? 简化下 flatMap:(f(x)) ->U?

这样看是一样的,但是看f(x),map 中的f(x) 是返回一个U flatMap的f(x)是返回一个U?
再看map 和flatMap 的最终返回值 都是U? Optional(U) 类型的,也就是map 拿到f(x)的之后,封装Optional类型再返回,而flatMap直接就是返回f(x)计算出来的Optional类型。

举个例子

map:{ x:int -> int in x * 2 } 其中这一块 { x:int -> int in x * 2 } 看成y = f(x) 这个表达式是传入x,传出x*2.

然后根据以下map的源码 可以看到 map将计算出来的值2x包上了一个Optional.Some(2x)
它就变成了Optional<Int>.some . map 这样做的的意义更多是为了链式调用

/// If `self == nil`, returns `nil`.  
/// Otherwise, returns `f(self!)`.
public func map<U>(@noescape f: (Wrapped) throws -> U) 
    rethrows -> U? {
switch self {
case .Some(let y):
    return .Some(try f(y))
case .None:
    return .None
}
}

再看下flatMap的传参 f(x) = {x:Int -> Int? in x * 2 } 注:大家都知道,是可以将Int类型的值赋值给Int?类型的,反过不行,看optional的构造函数就行。
然后看下flatMap拿到f(x)的实现,是直接返回了f(x)的计算结果

@warn_unused_result
public func flatMap<U>(@noescape f: (Wrapped) throws -> U?) 
    rethrows -> U? {
switch self {
case .Some(let y):
    return try f(y)
case .None:
    return .None
}
}

好了 现在咱们假设有个closure f(x),这个f(x) 有可能会return nil,也就是会返回optional.None 例如这样
可以看出来这个是吻合 flatMap的f的。接受Int 返回 Int? Int的封装。 但是如果你把它传给了map 也不会报错,但是有潜在的问题。

f(x) = { (a: Int) -> Int? in
    if a % 2 == 0 {
    return a
} else {
    return nil
}

潜在的问题:

let tq: Int? = 1
let b = tq.map { (a: Int) -> Int? in
    if a % 2 == 0 {
        return a  
    } else {
        return nil 
    }
}
//b为 Some<None> Optional(Optional(nil)) 这样第一次拆开盒子,发现里面不是空,而是另一个盒子c。只有把盒子c拆开才发现是空
if let c = b {
    print("not nil") //不会打印not nil
}

可以看到,map的参数 f(x) 的计算结果不希望是盒子类型(类似Optional),这个f(x)很单纯,你传进来x :Int 计算后 给你一个y:Int

如果上面的tq.map 换成 tq.flatMap{} 那就完美的符合了flatMap 的胃口,他就想要传进来的closure 是这样的:传一个值,返回一个盒子。

Functor 的函数定义是从「未封装的值」到「未封装的值」
Monad 的函数定义是从「未封装的值」到「封装后的值」

再啰嗦一遍,不管是Optional的 map 还是 flatMap 最终返回结果都必然是 Optional类型。

为了达到这个目的,map呢, 一直认为他的f(x)的计算结果是一个确切的值,例如 1 ,2 3,或者optional.None . 所以他就得将f(x)的结果放进一个盒子里,即封装成Optional。
flatmap呢,就简答了,他认为自己的f(x) 的计算结果就已经是一个Optional值--封装过得值了.当然你也可以这样写,最终得到仍然是一个Optional类型的值.这个还是归功于最后的 U?如果最终返回的不是一个Optional类型的,就会构造成一个Optional类型的。如果你改成str -> String??? 那么就会返回 String???类型
map 返回的永远比你f(x)里面写的多一层optional,而flatMap最终得到的最少是一层Optional。

let g = f.flatMap { str -> String in
        return str  // str 为Swift.String
    }//g 为 Swift.Optional<Swift.String> 

这样是为了更好的链式调用。不要被return前面的值所迷惑。

    学习 唐巧和雷纯峰 所分享的 Monad 
    http://blog.leichunfeng.com/blog/2015/11/08/functor-applicative-and-monad/
    http://blog.devtang.com/2016/03/05/swift-gym-4-map-and-flatmap/         
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容