F# 的血继限界(2)

某年某月,曾经某人希望 C# 出现 Java 匿名类的类似特性,然而最终他被 Java 的匿名类恶心到了。所谓的 Java 匿名类特性,即可以在项目里动态地创建一个类型,它继承了一个现有类,或者实现了一个现有接口。详情见《匿名类型的硬伤:围绕this的成员捕获策略

很庆幸 F# 有“对象表达式”。它很优雅地实现了这个特性,而且不带副作用。对象表达式的好处,不仅仅在于,它避免了为处理特定情况而创建太多类型,同时因为它是内联的,因此它享受了闭包的好处,把函数式发挥到了极致。以下例子是个常用的手段,它巧妙的结合了对象表达式和 use/using 关键字。这个例子表达了一种需求:它临时改变环境之后,必须自动恢复原状,也可以扩展到更多应用。

open System

let changeColor clr =

let orig = Console.ForegroundColor

Console.ForegroundColor <- clr

// 用对象表达式返回一个实现了 IDisposable 接口的对象

{ new IDisposable with

member x.Dispose () =

Console.ForegroundColor <- orig

}

[<EntryPoint>]

let main argv =

Console.WriteLine "原来的颜色"

do  use clr = changeColor ConsoleColor.Red

Console.WriteLine "变成红色"

Console.WriteLine "好贱,又变回来了"

Console.ReadLine () |> ignore

0

C# 里没有对象表达式,也没有其他“利用闭包动态实现子类”的可用方式。但是类似这个例子,C# 也可以通过一些函数式方法来实现。

1、可以 在 changeColor 函数里设定一个函数参数,让改变颜色后的操作写在一个函数里传入 changeColor。changeColor 在调用函数操作后再恢复原状。不过,这是另一种架构。我们不说某一种架构就比另一种架构好,但是能够按实际需求,灵活应用才是最好的。

2、写一个实现 IDisposable 接口的类,要求创建对象的时候传入一个用于恢复的函数。这种方式既然常用,写一个这样的类也不错。

时间: 2024-11-09 14:14:43

F# 的血继限界(2)的相关文章

F# 的血继限界(1)

如我们所见,在 F# 的产生和发展过程中,给 C# 引进了很多函数式的革新理念.然而这些革新仍未足以让 C# 进行完全函数式编程.C# 进行函数式编程时存在如下问题: 1.C# 中不能声明“局部不可变量”,不能处理尾递归优化. 很遗憾,不可变量和尾递归,可以说是函数式语言的绝对标识,至于有什么好处就不赘言. 而且这两点在C++都支持,把它们放在一起说也就是因为这个原因,它们可以算是 C# 相对 C++ ,进化不完全的“罪证”. C++中的 const 关键字,在C#里分成 const 和 rea

过分过分进货价获国家

http://f.dangdang.com/group/24554/3491082/http://f.dangdang.com/group/24554/3491087/http://f.dangdang.com/group/24554/3491094/http://f.dangdang.com/group/24554/3491099/http://f.dangdang.com/group/24554/3491105/http://f.dangdang.com/group/24554/349111

我们找个地方看好戏

http://v.qq.com/page/f/y/4/m041433ssun.html http://v.qq.com/page/f/y/4/m041433ssun.html http://v.qq.com/page/f/y/4/m04143o3lhg.html http://v.qq.com/page/f/y/4/m04144675h3.html http://v.qq.com/page/f/y/4/m04144k1k1j.html http://v.qq.com/page/f/y/4/m04

bat中for /f 如何截取任意行

一.概述 for命令开关有很多,/L,/F,/R.这里仅对含有/F的for进行分析,这个可能是最常用的,也是最强的命令,主要用来处理文件和一些命令的输出结果. 1.命令格式:(1).FOR /F ["options"] %%i IN (file) DO command(2).FOR /F ["options"] %%i IN ("string") DO command--注意双引号(3).FOR /F ["options"]

2017 ACM-ICPC 西安网络赛 F.Trig Function Chebyshev多项式

自己太菜,数学基础太差,这场比赛做的很糟糕.本来想吐槽出题人怎么都出很数学的题,现在回过头来想还是因为自己太垃圾,竞赛就是要多了解点东西. 找$f(cos(x))=cos(nx)$中$x^m$的系数模998244353. wolfram alpha查了这个函数无果,得到了一堆sinx和cosx以及一个复指数的方程,其实应该推个几项再用数列查询查查看的,然后就会知道是Chebyshev polynomials 查WIKI直接就有通项公式了.然后就比较简单的了. 连方程都看不出来就别想着推导公式了.

tailf、tail -f、tail -F三者区别

tail -f      等同于--follow=descriptor,根据文件描述符进行追踪,当文件改名或被删除,追踪停止 tail -F     等同于--follow=name  --retry,根据文件名进行追踪,并保持重试,即该文件被删除或改名后,如果再次创建相同的文件名,会继续追踪 tailf        等同于tail -f -n 10(貌似tail -f或-F默认也是打印最后10行,然后追踪文件),与tail -f不同的是,如果文件不增长,它不会去访问磁盘文件,所以tailf特

F(x)

F(x) Time Limit: 1000/500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description For a decimal number x with n digits (AnAn-1An-2 ... A2A1), we define its weight as F(x) = An * 2n-1 + An-1 * 2n-2 + ... + A2 * 2 + A1 * 1. No

求f(k)=k^k(k=1...n)的前n项和

求f(k)=k^k(k=1...n)的前n项和. 程序实现: #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> long long My_Mul_Sum(int *n)//封装了一个求k^k的前n项和的函数 { int k = 1; long long sum = 0;//定义为long long是为了防止数据较大,容易溢出 for (k = 1; k <= n; k++) { int count = 0, mul = 1;//count

JSP -&gt; f:loadBundle用法

jsp中出现<f:loadBundle basename="messages_zh_CN" var="msgs" /> 还有src目录下有messages_zh_CN.properties等类似文件. 看了下面的教程你就知道这些是什么文件以及做什么用的. 一下部分来自http://javazheng.iteye.com/blog/766294 1,首先,为不同的语言分别准备一个.properties文件.比如,若要支持英文,中文,日文,则英文可以为Mes