惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
Microsoft Security Blog
Microsoft Security Blog
云风的 BLOG
云风的 BLOG
B
Blog
The Register - Security
The Register - Security
L
LangChain Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
N
Netflix TechBlog - Medium
F
Full Disclosure
The GitHub Blog
The GitHub Blog
Recorded Future
Recorded Future
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Blog — PlanetScale
Blog — PlanetScale
Jina AI
Jina AI
美团技术团队
宝玉的分享
宝玉的分享
Hugging Face - Blog
Hugging Face - Blog
阮一峰的网络日志
阮一峰的网络日志
G
Google Developers Blog
大猫的无限游戏
大猫的无限游戏
S
SegmentFault 最新的问题
D
DataBreaches.Net
Martin Fowler
Martin Fowler
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Google DeepMind News
Google DeepMind News
WordPress大学
WordPress大学
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - Franky
The Cloudflare Blog
博客园 - 【当耐特】
U
Unit 42
月光博客
月光博客
T
The Blog of Author Tim Ferriss
博客园 - 叶小钗
博客园 - 聂微东
I
InfoQ
B
Blog RSS Feed
Apple Machine Learning Research
Apple Machine Learning Research
Cyberwarzone
Cyberwarzone
V
V2EX
S
Securelist
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
S
Security @ Cisco Blogs
PCI Perspectives
PCI Perspectives
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
H
Heimdal Security Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Hacker News
The Hacker News
D
Darknet – Hacking Tools, Hacker News & Cyber Security
T
Tor Project blog

博客园 - yushih

初学Erlang,写两个程序玩玩 Django杂记: super与metaclass,locmem有害 一直没弄明白的事--为什么招聘要求会有“面向对象分析与设计”这一项 用Linux的iptables和Python模拟广域网 Python programming with goto 实用主义之过--Pragmatic Version Control using Subersion, 2nd Ed.的书评 Python把C语言打得满地找牙 信春哥!Python递归原地满状态变显式堆栈!入教即送尾递归优化! STL的binary search算法正确性的初步说明 关于文档标准之争的一点旁注 有关Ruby eval的一点编程风格 Design pattern一来,动态语言就笑了 - yushih - 博客园 完全没有领会“电子商务”的真谛 超级奇怪的F#格式错误 JAOO的魅力所在 一个Ruby idiom C++ hack:将C++编译器的类型检查转化为SLR(1)解析器 Quotes The Ruby Programming Language第一版非官方修正
F#的一点糖
yushih · 2008-10-18 · via 博客园 - yushih

重口味警告:本篇适合于追求代码直观到偏执狂地步,和宁愿绞尽脑汁减少几次击键的程序员,不喜勿入!

在Ruby里我们可以写出这样的代码:

hash.if_has_key k do |val|
#do sth. with val
end
 

这段代码描述性太强了,以至不需要解释就能让人明白。而且对比普通写法:

if hash.has_key k then
 val = hash[k]
 ...

end

< p>省了不少打字的功夫。为了在F#里也有这样的效果,我想了两种方法。首先,可以模拟Ruby。实现if_has_key的关键一是开放 class--事前要将if_has_key方法加入hash的类,二是block。F#和C# 3.0一样支持extension methods,而lambda expression可以代替block(虽然不完美),因此可以这样:

#light

type System.Collections.Generic.IDictionary with
    member this.if_has_key k f =
        if this.ContainsKey k then
            f this.[k]
        else
            ()

于是:

let tbl = dict [(1, "one"); (2, "two");]

tbl.if_has_key 1 (fun val->
    print_any val |>ignore)

可是fun关键字实在扎眼,也只能感叹Ruby的设计至少在格式层面是很巧妙的了。第二种方法利用F#的active pattern功能:

let (|HasKeyVal|_|)<'kt, 'vt> k (d:System.Collections.Generic.IDictionary<'kt, 'vt>)  =
    if d.ContainsKey k then Some(d.[k])
    else None

于是:

match tbl with
| HasKeyVal 2  v -> print_any v
| _ -> ()

缺点一是match关键字在这个地方不伦不类,二是要跟个尾巴|_->() 。好处是可以像swich包含多个case一样:

match tbl with
| HasKeyVal k1 v -> ...
| HasKeyVal k2 v -> ...
| HasKeyVal k3 v -> ...
| _-> ()

程序会依次测试tbl是否包含k1,k2,k3。这样的程序对比起用if...then...elseif...else写出来的版本节省就比较可观了。