拼吾爱程序人生

首页 » .Net编程 » F# » F#学习之路(6)列表
cobra - 2008-9-6 8:15:00
列表在函数式编程中占据着重要的位置。在Lisp语言中,一切皆是列表,就连函数也是列表,列表在Lisp语言中发挥到了极致。F#语言列表语法来源于Ocaml,与Haskell语言也基本一致。本文只会讲解一些常用的使用方法,要很好的掌握列表,各位朋友可以google一下相关的内容。网络上对列表讨论比较深刻的大多以Haskell语言为例(Lisp语言列表很强大,但与大多数函数式语言列表的区别太大,不好借鉴)。

    在讨论列表之前,我将对前几篇文章做个简要的说明,因为CTP版的改动,有一些讨论不正确了,我在这里更正一下。

    1、名称空间必须使用完全限定名打开,名称空间不可以取别名。

    2、元组类型互操作上发生了变动。

    新增了两个类型来提供互操作上的支持。TupleEnd,TupleNested,彻底解决了互操作上的不一致性。

Code


对应的c#签名:

Code


C#语言如果使用以下的规则,F#语言就可以正确的识别出元组。

      如果元组元素个数小于7,使用Tuple泛型,下面的代码,F#可以正确的转换为(1,2,3);

Code


等于七个元素,第七个元素使用TupleEnd包装,下面的代码,F#可以正确的转换为(1,2,3,4,5,6,7)

Code


大于七个元素的元组,七个元素以上的使用TupleNested包装,下面的代码,F#可以正确的转换为(1,2,3,4,5,6,7,8)。

Code


为了给大家一个直观的映象,我给出完整的调用例子。

   

    首先请建立一个c#类库工程,引用FSharp.Core.dll

Code


在F#中分别调用

Code


你会发现调用T2,T4均出错。T6不会出错,但可能不是你想要的结果。

   
 附件: 您所在的用户组无法下载或查看附件


 附件: 您所在的用户组无法下载或查看附件
   







(文/lvxuwen  出处/博客园)

 您可能对 [F#] 的这些文章也感兴趣:

F# 之旅(六):F#代码的组织
F# 之旅(四):面向对象编程(上)
F# 之旅(二):函数式编程(下)
F#学习之路 (1)什么是函数式编程
F# 之旅系列文章
F#最新信息:MonoDevelop、新书和新的CTP
F# 之旅(四):面向对象编程(中)
从C# 3.0到F#
F#语言2008年9月CTP版已经更新
F#语言中的WPF
cobra - 2008-9-6 8:18:00
现在让我们正式讨论F#中的列表。

    一、如何定义列表

    在F#中定义一个列表,有几个方法。

    1、使用字量值

Code


使用中括号'[',']',元素之间用分号分隔。不同于元组类型,元组使用'(',')',元素之间使用逗号分隔。

    F#中的列表是链表,列表元素必须是相同类型,列表是不可变的,因此定义后将不能改变。

    F#中定义一个空列表,有三种方法。它们在使用上有一些细微的差别。

Code


列表上定义了一个 @ 操作符,用于将一个列表追加到另一个列表的尾部,生成一个新的列表。而 :: 操作符,则将一个元素添加到一个列表的首部,形成一个新的列表。注意所有操作的列表本身不会改变。这种行为类似.net的string类型。

   

    2、使用范围表达式

Code


3、使用序列表达式

Code


关于序列将在以后的博客中讨论,序列是一种计算表达式的实现。



    二、列表比较。

Code


列表类型可以很方便的进行值比较,要使用引用比较请使用obj.ReferenceEquals

Code


三、访问列表元素

Code


列表索引从0开始。



    四、使用列表类型属性

Code


五、访问List模块操作列表

Code


上面的代码,使用namespace定义了一个FSharpLearning名称空间,使用type给int类型取了一个更有意义的名称LineNO。

    并且使用type定义了一个Order记录类型和Product记录类型,以及OrderStatus联合类型。

    之后使用module定义了一个子模块Order,并且这里使用[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]标注了Order模块。并告诉编译器在Order模块名后面加上Module作为模块名。前面说过顶层作用域不允许重名。

    Order模块中定义了几个函数,用来操作Order记录类型。之后,我们在ListTest模块中分别调用了这些定义的函数。

    List模块中函数较多,主要介绍三个,其它函数使用方法类似。

Code


|>前向管道操作符。上面的字法等价于List.iteri (fun i num ->printfn "index %d:%d" i num) numbers

      List.iteri带有索引,还有一个List.iter不带索引,通常这两个函数用来遍历列表。

Code


List.map的函数类型为('a->'b)->'a list->'b list

    map函数通常用来操作列表中每个元素,生成新的列表。

Code


List.reduce_left函数类型为('a->'a->'a)->'a list ->'a

    reduce_left函数从左到右依次取出列表中两个元素操作。通常称为归约。



    六、列表与模式匹配

Code


总结:

    1、列表用于表示相同类型的一组数据的集合,在F#中大数据量集合类型应优先使用seq序列,因为序列是惰性的。

    2、列表是一个combinator,列表的类型定义为:

          type 'a list=

          |([])

          |( :: ) of 'a *'a list

    一个[1;2;3]的列表本质上是1::2::3::[],最具体的说是op_Cons(1,op_Cons(2,op_Cons(3,op_Nil)))

    op_Nil是[]的操作符名,op_Cons是::的操作符名。

    一个列表可以看作第一个元素(称为首部Head)与后面所有元素(称为尾部Tail)的组合。

    这样两个操作构成了列表的灵魂,深入研究组合子非常必要。
1
查看完整版本: F#学习之路(6)列表
Modify by pin5i DZNT_ExpandPackage 2.1.3258 2007-2008 pin5i.com
  Total Unique Visitors: