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

推荐订阅源

freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
腾讯CDC
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
L
LINUX DO - 热门话题
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Project Zero
Project Zero
V
Vulnerabilities – Threatpost
Cisco Talos Blog
Cisco Talos Blog
P
Palo Alto Networks Blog
C
Cisco Blogs
A
Arctic Wolf
月光博客
月光博客
The GitHub Blog
The GitHub Blog
T
The Blog of Author Tim Ferriss
量子位
小众软件
小众软件
Latest news
Latest news
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Microsoft Security Blog
Microsoft Security Blog
T
The Exploit Database - CXSecurity.com
Security Latest
Security Latest
N
Netflix TechBlog - Medium
K
Kaspersky official blog
人人都是产品经理
人人都是产品经理
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园_首页
Y
Y Combinator Blog
P
Proofpoint News Feed
H
Hackread – Cybersecurity News, Data Breaches, AI and More
M
MIT News - Artificial intelligence
T
Threat Research - Cisco Blogs
S
Schneier on Security
D
Docker
Scott Helme
Scott Helme
MyScale Blog
MyScale Blog
Spread Privacy
Spread Privacy
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
GbyAI
GbyAI
有赞技术团队
有赞技术团队
Google DeepMind News
Google DeepMind News
The Hacker News
The Hacker News
H
Help Net Security
Simon Willison's Weblog
Simon Willison's Weblog
J
Java Code Geeks
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Tenable Blog
B
Blog
Know Your Adversary
Know Your Adversary
IT之家
IT之家

博客园 - 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写出来的版本节省就比较可观了。