我一直在使用Visual Studio 2010中的F#.我是一名开发人员,在面向对象语言(如C#和Java)方面拥有更多的代码/架构设计经验.
为了扩展我的技能并帮助做出更好的决策,我尝试使用不同的语言来做不同的事情.特别是使用函数语言(在这种情况下为F#)"正确"编码.
一个简单的例子是生成一些XML,然后添加一些过滤器来消除一些元素.
这是我的代码:
open System open System.Xml.Linq let ppl:(string * string) list = [ ("1", "Jerry"); ("2", "Max"); ("3", "Andrew"); ] /// Generates a Person XML Element, given a tuple. let createPerson (id:string, name:string) = new XElement(XName.Get("Person"), new XAttribute(XName.Get("ID"), id), new XElement(XName.Get("Name"), name) ) /// Filter People by having odd ID's let oddFilter = fun (id:string, name:string) -> (System.Int32.Parse(id) % 2).Equals(1) /// Open filter which will return all people let allFilter = fun (id:string, name:string) -> true /// Generates a People XML Element. let createPeople filter = new XElement(XName.Get("People"), ppl |> List.filter(filter) |> List.map createPerson ) /// First XML Object let XmlA = createPeople oddFilter /// Second XML Object let XmlB = createPeople allFilter printf "%A\n\n%A" XmlA XmlB /// Waits for a keypress let pauseKey = fun () -> System.Console.ReadKey() |> ignore pauseKey()
我的问题是:在这种情况下我做得怎么样?哪些部分可以做得更好?
我真的很期待一些想法,我也很兴奋熟悉功能范例!:)
提前致谢
原则上,您的代码是可以的.
从语法的角度来看,只有一些点可以简化.
let ppl:(string * string) list = [ ("1", "Jerry"); ("2", "Max"); ("3", "Andrew"); ]
编译器能够自己推断出大多数类型:
let ppl = [ "1", "Jerry"; "2", "Max"; "3", "Andrew" ]
当然,由于curry,你可以像这样重写你的过滤器:
let oddFilter (id:string, name:string) = (int id) % 2 = 1 let allFilter (id:string, name:string) = true
最大的改进是将索引与名称分开,让程序进行编号.您不必使用字符串而不是数字,并且可以使用更多惯用的无元组函数:
let ppl = [ "Jerry"; "Max"; "Andrew" ] let oddFilter id name = id % 2 = 1 let allFilter id name = true let createPerson id name = ...
那个部分
ppl |> List.filter(filter) |> List.map createPerson
将改写为
[ for (index, name) in List.mapi (fun i x -> (i, x)) do if filter index name then yield createPerson (string index) name ]