PLT 板


LINE

看板 PLT  RSS
因为有人提到,所以复习了一下.. 1. Y combinator in Haskell Y combinator 在 untyped lambda calculus 中是 \f -> (\x -> f (x x)) (\x -> f (x x)) 试着写成 Haskell: y :: (a -> a) -> a y f = (\x -> f (x x)) (\x -> f (x x)) f 的型别是 a -> a, 而 y 取 f 的 fixed-point, 所以 y 的型别是 (a -> a) -> a. 但是这个型别一看就有问题:把 type 看成逻辑的话, 这个 type 若有证明就会有 inconsistency. 果然, Haskell 不让这个程式 typecheck: Occurs check: cannot construct the infinite type: t = t -> a Probable cause: `x' is applied to too many arguments In the first argument of `f', namely `(x x)' In the expression: f (x x) 操作上的理由是:在 (x x) 之中,x 的型别又是 t -> a, 又是 t, 而 t = t -> a 递回定义。 解决方法也很简单,就头痛医头脚痛医脚,做一个 t 与 t -> a 同构的递回型别罗。 data Fix a = Rec (Fix a -> a) -- Fix a 和 Fix a -> a 同构 有了 Fix 就可以写 Y combinator 了。 y :: (a -> a) -> a y f = (\(Rec x) -> f (x (Rec x))) (Rec (\(Rec x) -> f (x (Rec x)))) 和前一个版本比较,这里多了很多 Rec,其实是在告诉 typechecker 何时要把 Fix 展开。 2. 用 Y 定义递回函数 假设 Haskell 不允许递回定义(正确地说,允许递回资料型别,但 不允许递回的 term),那要怎麽写递回函数呢? 递回版本的阶层是这麽写的: fact :: Int -> Int fact 0 = 1 fact (n+1) = (n+1) * fact n 没有递回的话,就用 Y 取 fixed-point 罗。首先定义这个 factF: factF :: (Int -> Int) -> (Int -> Int) factF g 0 = 1 factF g (n+1) = (n+1) * g n 和 fact 的差别是 factF 只做 fact 的第一层。注意 factF 的型别。 然後 fact 就是 factF 的 fixed-point: fact :: Int -> Int fact = y factF 由此可知一个语言如果有提供 closure, 就可以不用把递回当作 primitive. 3. Mutual Recursion Mutual recursion 其实也是一样的,只是同时定义一组东西。 比如说一般 even 和 odd 可以这样定: even, odd :: Int -> Bool even 0 = True even (n+1) = odd n odd 0 = False odd (n+1) = even n 如果没有递回,就定义一个从「一对」函数到一对函数的函数: evenOddF :: (Int -> Bool, Int -> Bool) -> (Int -> Bool, Int -> Bool) evenOddF (ev, od) = (\n -> if n == 0 then True else od (n-1), \n -> if n == 0 then False else ev (n-1)) evenOddF 拿一对函数 (ev,od),产生一对函数,各自只做 even 和 odd 的第一层。本来该是递回的地方分别呼叫 od 和 ev. (如果该语言没有 pair, 就用 lambda 来模拟。) 然後我们也用 Y 取 evenOddF 的 fixed-point: evenOdd :: (Int -> Bool, Int -> Bool) evenOdd = y evenOddF even 就是第一个,odd 就是第二个: even = fst evenOdd odd = snd evenOdd 只是还有一点小问题:在 Haskell 中 y evenOddF 不会终止。 简单的解决方法是把 evenOddF (ev, od) = ... od .. ev ... 改成 evenOddF evod = ... snd evod ... fst evod ... 看起来比较漂亮,其实一样的方法是用 lazy pattern: evenOddF ~(ev, od) = ... od .. ev ... 这样就可以罗! *Main> even 10 True *Main> odd 10 False --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 123.192.160.134
1F:推 SansWord:Cool! Thanks! 06/04 00:58







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:WOW站内搜寻

TOP