方法一,records of functions with local states:
#light这是在functional programming language中引入objects的经典方法。SICP中有讲述了用scheme实现这种套路,因此这种方法看上去更fp一些,但是有以下缺点:
type EnvModelObj<'T> = { get: unit -> 'T; set: 'T -> unit }
let NewEnvModel initState =
let state = ref initState
{
set = (fun x -> state := x);
get = (fun () -> !state)
}
let o1 = NewEnvModel 1
o1.set 3
print_any (o1.get ())
- 先要定义一个代表这个类的界面的record type,然后定义一个返回这个record的函数,居然和C++定义class的方法十分像!两个定义中包含了重复的信息,违反了DRY原则。
- 所有的成员,因为必须使用ref变量,都必须box,效率受损。
- 这是一个F#类,其它.NET语言看不懂这个类。
感觉有点怪异,不理解F#为什么要有这么一个feature,为了实践Perl的Many ways to do one thing哲学吗?
type RecordWithMemberFunction =
{ mutable state : int}
with
member this.get () =
this.state
member this.set x =
this.state <- x static member ctor initState =
{ state = initState }
end
let o3 = RecordWithMemberFunction.ctor 5
o3.set 6
print_any (o3.get ())
方法三:first-class .NET class
type Class<'T> = class这样定义的class是标准的.NET class,可以给其它语言使用,但是用F#定义这样一个class,也比其它语言省不了多少“笔墨”了。
val mutable state: 'T
new initState as this =
{ state = initState }
then
print_string "initalizing "
print_any this
print_newline ()
member this.get () = this.state
member this.set x =
this.state <- x
end
let o4 = new Class7
o4.set 8
print_any (o4.get ())
末了,我要告诉大家,blogger.com把我的代码的缩进搞得一塌糊涂,简直无可救药,再次证明了我的理论:the (x)html web sucks sucks sucks。
No comments:
Post a Comment