维坦
感谢您的关注!
-
Jul301 Comment
我本人是通过 F# 了解了 .NET
进而了解了一些 C#
因此我对于 F# 的好多见解是片面的例如: 我曾经在学习 F# 之后好久都不能理解 type
今天见到一篇好文, 文章的作者是从 C#3.0 的角度看待 F#, 深入浅出, 角度客观, 可以说是难得的好文~!~
从 C#3.0 到 F#
作者:Allen Lee -
Jul246 Comments
最后更新: 2008年7月24日 (21篇)
原文作者: Kean Walmsley
文档格式: Word文档 (*.doc) | 7zip (*.7z)完整下载: http://www.box.net/shared/qsmfdafvcn
文章目录:
- A simple 3D LOGO implementation inside AutoCAD using F#
在 AutoCAD 中使用 F# 实现 3D LOGO 的简单应用
- Sectioning an AutoCAD solid using F#
使用 F# 分割 AutoCAD 实体
- Generating fractals inside AutoCAD using F#
在 AutoCAD 中使用 F# 生成分形
- Initialization code in your F# AutoCAD application
AutoCAD程序初始化F#代码
- Using AutoCAD 2009 s new transient graphics API to show point clouds from F#
利用F#和AutoCAD 2009的新API临时图形来显示点云
- New APIs in AutoCAD 2009
AutoCAD 2009中新的API
- Recursive F# code to generate random point clouds inside AutoCAD
递归F#代码在AutoCAD中产生随机点云
- Using Reflector to diagnose tail call optimization in F#
使用Reflector对F#进行诊断跟踪优化
- Pointing at clouds more random musings on AutoCAD and F#
点云 关于AutoCAD和F#的更多遐想
- Parallelizing robotic AutoCAD hatching with F# and .Net
使用F#及.NET实现并行智能AutoCAD填充
- Robotic hatching inside AutoCAD using F# and .Net
使用F#及.NET在AutoCAD中实现智能填充
- Mardi Gras Super Tuesday and F#
狂欢节 超级周二与F#
- Using F# to simulate hardware behaviour
使用F#模拟硬件行为
- Using F# Asynchronous Workflows to simplify concurrent programming in AutoCAD
在AutoCAD中使用F#异步工作流程简化并行程序
- Turning AutoCAD into an RSS reader with F#
在AutoCAD中使用F#实现RSS阅读器
- Metaprogramming with AutoCAD - Part 3
元编程与AutoCAD 第三部分
- Metaprogramming with AutoCAD - Part 2
元编程与AutoCAD 第二部分
- Metaprogramming with AutoCAD - Part 1
元编程与AutoCAD 第一部分
- Getting the total volume of 3D solids in an AutoCAD model using F#
使用F#获取AutoCAD模型中3D实体的总体积
- More fun with F# and AutoCAD string extraction and manipulation
F#更多有趣的东西与AutoCAD字符串的提取及操作
- A mathematical F# application integrating with AutoCAD via .NET
一个AutoCAD F# .NET的完整数学程序
- F# - a perfect fit for AutoCAD .NET programming
F# - 非常适合AutoCAD .NET程序开发么
My first F# application for AutoCAD
我的第一份用于AutoCAD的F#程序
部分下载: http://www.box.net/shared/x8d3ydgqb2
关于 F# 语言:
- F# 是一门函数式编程语言! (Functional Programming Language)
- 官方网站: http://msdn.microsoft.com/zh-cn/fsharp/
- 目前已经进入产品化阶段, 预计今夏(2008年)发布第一个CTP版
- 维护者: Don Syme
- 发布方式: Visual Studio 扩展
什么是函数式编程?
简单的定义是: 在函数式语言中, 函数是第一等公民.
函数式语言其实比你想象中的要多得多, 只不过它们长期处在计算机技术发展的边缘, 所以好多都是不为人知.
如: LISP, Scheme,Perl, ML, Miranda, Haskell, XSLT, Ruby, erlang, Ocaml 等等.F# 有什么用?
形象的比喻: 用C#吸引C/C++程序员, 用VB.NET替换VB6, 用J#拉拢JAVA程序员, 那么F#就是招安那些处在边缘的函数式小语种, 这也就是为什么Kean会说 - F#是最适合AutoCAD开发的编程语言 - 的原因!Kean Walmsley是Autodesk的专家, 他从2007年10月31日起连续发表关于使用 F# 开发 AutoCAD 的文章, 但是由于我们平常所见到的编程技术多半是类 C 技术, 再加上 F# 时间较短, 所以Kean所研究的技术显然是有些超前了, 但是他对这门语言的崇拜显然已经达到了宗教般的高度, 这使我坚信他所追求的一定很有价值!
由于一些原因, Kean的博客不容易访问, 因此我会不间断的摘录并坚持翻译, 但仅限于F#有关的文章.
有趣的是: 在 Google 中搜索 F# 会返回近百万个匹配的结果, 而在百度中搜索就只会返回0个.
- A simple 3D LOGO implementation inside AutoCAD using F#
-
Jul231 Comment
之前的一篇文章提到过一种逆向思维求解MD5的方法.
后来发现真的有人这么做了, 其中数据量最大的网站标称自己拥有4T的数据量, 可以解8位以下的数字和字母组合.
即然是之前自己有过的想法, 那就拿F#来具体实现一下吧:
#light namespace ViTarn module MD5 open System open System.Data open System.Diagnostics open System.IO open System.Security.Cryptography open System.Text // sqlite.phxsoftware.com #r "System.Data.SQLite.DLL" open System.Data.SQLite // 数据库名 let dbFile = "db.sqlite" // 连接字符串 let connString = let csb = SQLiteConnectionStringBuilder () csb.DataSource <- dbFile csb.ConnectionString // 秒表 let watch = new Stopwatch () watch.Start() // 为调试方便 输出对象并换行 let debug x = x |> print_any Console.WriteLine () // 从' '到'~'共95个常用于密码的字符 可以当成95进制看待 let n2cl n = let rec prase n l = let d = n % 95 let c = d + 32 |> char let d = n - d if d > 95 then prase (d / 95) (c :: l) else c :: l |> List.to_array prase n [] // MD5加密字符串 let md5 (str : string) = use md5Hasher = MD5.Create () str |> Encoding.Default.GetBytes |> md5Hasher.ComputeHash |> Seq.map (fun x -> x.ToString "x2") |> Seq.fold (fun x y -> x + y) "" // 创建数据库 if dbFile |> File.Exists |> not then dbFile |> SQLiteConnection.CreateFile use conn = new SQLiteConnection (connString) let sql = "PRAGMA auto_vacuum = 1; " + "PRAGMA encoding = 'UTF-8'; " + "PRAGMA page_size = 4096; " + "PRAGMA synchronous = OFF; " + "CREATE TABLE md5 (p VARCHAR(42) NOT NULL COLLATE NOCASE, s VARCHAR(9) NOT NULL COLLATE NOCASE);" use cmd = new SQLiteCommand (sql, conn) conn.Open () cmd.ExecuteNonQuery () |> ignore conn.Close () let main _ = let sql = "INSERT INTO md5 " + "VALUES(?, ?); " use conn = new SQLiteConnection (connString) use cmd = new SQLiteCommand(sql, conn) cmd.Parameters.AddRange [|new SQLiteParameter(); new SQLiteParameter()|] conn.Open () use tr = conn.BeginTransaction () cmd.Transaction <- tr for i = 0 to 857374 do let s = new String (n2cl i) let p = md5 s cmd.Parameters.[0].Value <- p cmd.Parameters.[1].Value <- s cmd.ExecuteNonQuery () |> ignore if i % 10000 = 0 then i |> debug tr.Commit() conn.Close () main () watch.Elapsed |> debug Console.ReadKey()
为什么是857374?
95 * 95 * 95 - 1 = 857374模拟的95进制, 是从"空格"(' ')到波浪线('~')的, 用ASCII表示就是32到126.
所在0 to 857374代表' '到'~~~'在我的电脑上耗时00:01:08
CPU: AMD3000+
RAM: 1G
以DEBUG模式运行
最终产生的数据库约36M+ -
Jul211 Comment
背景:
嘎纳广告节(Cannes Lions Advertising Campaign)源于嘎纳电影节, 1954年, 由电影广告媒体代理商发起组织了嘎纳国际电影广告节, 希望电影广告能同电影一样受到世人的认同和瞩目.
吉百利(Cadbury Schweppes): 全球第一大糖果公司, 第二大口香糖公司, 第三大软饮料公司.歌曲: In the air tonight
歌手: Collins phil
专辑: Face Value
-
Jul18No Comments
近来正在试着用 F# 实现自承载 WCF 服务, 供 Silverlight 调用.
一些数据会通过 "添加服务引用" 这一功能, 实现从 F# 到 C# 的转换. 正好借此机会看下会发生什么样有趣的事情.由于我要在服务端读取数据库, 之前的 LINQ to SQL 经历告诉我, 我应该为数据库的每个表定义相应的类, 以 Boy 表为例:
(* F# 在类(Class)的定义方面是很灵活的 从某种意义上讲 对类的表达近乎恶搞 因为类(Class)对 F# 来说只不过是个表达式而已 *) // 可以这样: type Boy1 = val mutable _name :string val mutable _age :int member t.Name with get() = t._name and set(v) = t._name <- v member t.Age with get() = t._age and set(v) = t._age <- v new () = { _name = "" _age = 0 } // 这种形式要求必须实例化之后才能使用 let boya = let boy = new Boy1() boy._name <- "colder" boy._age <- Int32.MaxValue boy // 或 let boyb = new Boy1(Name = "colder", Age = Int32.MaxValue) // 还可以定义成这样: type Boy2(name :string, age :int) = let mutable _name = name let mutable _age = age member t.Name with get() = _name and set(v) = _name <- v member t.Age with get() = _age and set(v) = _age <- v // 实例化时参数即为字段 let boyc = new Boy2("colder", Int32.MaxValue) // 这两种方式定义的类 都是在模仿 C# 定义类的方式 // 不过怎么看都没有 C#3.0 使用的 { get; set; } 形式简单 // 可不可以使用 Records 呢? // 答案是肯定的 生成的客户端代码并没有区别 type Boy = { mutable Name :string mutable Age :int } // 实例化也是最简单的 let boyd = { Name = "colder" Age = Int32.MaxValue }
验证的依据很简单, 在服务端开放数据契约和服务契约, 之后生成客户端代码, 看是否有异常就可以了
// 给 Boy 记录加上相关的属性 [<DataContract(Name="Boy")>] type Boy = { [<DataMember(Order = 1)>] mutable Name :string [<DataMember(Order = 2)>] mutable Age :int } // 返回值采用标准的 List<T> 泛型 // 也就是微软官方视频教程中提到的 LINQ 表达式的 ToList() 方法返回的类型 [<ServiceContract(Name = "Wcf")>] type Wcf() = let boy = { Name = "colder" Age = Int32.MaxValue } [<OperationContract>] member t.BoyListT() = let list = new System.Collections.Generic.List<Boy>() list.Add boy list
// 以下是客户端服务引用自动生成的代码片段 [System.Diagnostics.DebuggerStepThroughAttribute()] [System.Runtime.Serialization.DataContractAttribute(Name="Boy", Namespace="http://schemas.datacontract.org/2004/07/")] public partial class Boy : object, System.ComponentModel.INotifyPropertyChanged { private string NameField; private int AgeField; [System.Runtime.Serialization.DataMemberAttribute()] public string Name { get { return this.NameField; } set { if ((object.ReferenceEquals(this.NameField, value) != true)) { this.NameField = value; this.RaisePropertyChanged("Name"); } } } [System.Runtime.Serialization.DataMemberAttribute(Order=1)] public int Age { get { return this.AgeField; } set { if ((this.AgeField.Equals(value) != true)) { this.AgeField = value; this.RaisePropertyChanged("Age"); } } } public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; protected void RaisePropertyChanged(string propertyName) { System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged; if ((propertyChanged != null)) { propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); } } }
上面这个例子生动的说明: 什么时候该使用 Class, 什么时候该使用 Records.
个人理解, 有行为的才是 Class, 只是数据的就应该是 Records.难怪蔡学镛先生会提醒初学 F# 的人 宁可矫枉过正 也要保持 FP 的原汁原味 只有这样才能深刻体会 FP 的真谛
数据契约弄清楚了, 那 WCF 操作契约的返回值可不可以采用 F# 常见的 list 或 seq 之类的呢? 试一下便清楚了!
// 修改契约 返回 list, 也就是 F# 特有的数据类型 Boy list. // seq 会返回同样的效果, 不再重复了. [<ServiceContract(Name = "Wcf")>] type Wcf() = let boy = { Name = "colder" Age = Int32.MaxValue } [<OperationContract>] member t.BoyList() = [boy]
// 生成的 C# 代码是个畸型的怪胎... // 不可思议的类名: ListOfBoyMTRdQN6P [System.Diagnostics.DebuggerStepThroughAttribute()] [System.Runtime.Serialization.DataContractAttribute(Name="ListOfBoyMTRdQN6P", Namespace="http://schemas.datacontract.org/2004/07/Microsoft.FSharp.Collections")] public partial class ListOfBoyMTRdQN6P : object, System.ComponentModel.INotifyPropertyChanged { public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; protected void RaisePropertyChanged(string propertyName) { System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged; if ((propertyChanged != null)) { propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); } } }
看到了吧, 此 list 非彼 List, 真的想不通把 Boy 放到 list 以后究竟发生了什么, 导致离开 F# 环境, 取出的 Boy 就不再是 Boy 了 (ListOfBoyXXXXXXXX)
我并不是一个像 Q.yuhen 这样内功深厚的武林高手, 否则我会一直追问直到找出原因. 事实上我只是个样样好奇却样样平庸的功夫小子, 玩弄些花拳绣腿罢了, 所以尝试只能在此结束, 无法继续找出真正的答案了.
-
Jul15No Comments
F# 1.9.4.19 版发布了, 这是个微量更新版本, 主要涉及以下三个方面:
- 修正与 Mono 的兼容性问题.
- WebRequest.GetResponseAsync 方法从 FSharp.Core.dll 中移除了.
之前因为这个问题导致 F# 无法摆脱对 .NET 完整版的依赖, 也因此无法编译 Silverlight 这类 Core-CLR 代码.
但问题是, 即使如此我们又如何使用 F# 来实现 Silverlight2 呢? 说真的, SL2 的编译和打包方式真的很诡异, 之前曾经有研究过, 那些 xaml 文件会被嵌入"项目名.g.xaml", 而且是前所未有的MemoryStream类型, 几次下来还是一头雾水. 期待 Demo 的出现. - 修正与 .NET 3.5 SP1 Beta 的兼容性问题
详见 Don 的原文
-
Jul8No Comments
虽然上篇文章中提到 SQLite 是弱类型数据库, 但对于 System.Data.SQLite 来说, 为了更好的与 Ado.NET 2.0 互操作, 作者仍然建议在创建表的时候就指定类型, 以方便程序进行类型转换, 下面是类型关键字列表:
DbType.Boolean
BIT
YESNO
LOGICAL
BOOLDbType.Byte
TINYINTDbType.Int16
SMALLINTDbType.Int32
INTDbType.Int64
INTEGER
BIGINT
COUNTER
AUTOINCREMENT
IDENTITY
LONGDbType.Single
REALDbType.Double
DOUBLE
FLOATDbType.Decimal
NUMERIC
DECIMAL
MONEY
CURRENCYDbType.String
CHAR
NCHAR
VARCHAR
NVARCHAR
TEXT
NTEXT
LONGTEXT
LONGCHAR
LONGVARCHAR
STRING
MEMO
NOTEDbType.Binary
BLOB
BINARY
VARBINARY
IMAGE
GENERAL
OLEOBJECTDbType.Guid
GUID
UNIQUEIDENTIFIERDbType.DateTime
TIME
DATE
DATETIME
SMALLDATE
SMALLDATETIME
TIMESTAMP有两点需要注意:
- SQLite 主键默认的 INTEGER 类型对应的是 Int64, 而 INT 对应的是 Int32.
- 日期和时间类型最终存储为字符串, 所以格式必须符合ISO8601标准:
"yyyy-MM-dd HH:mm:ss",
"yyyyMMddHHmmss",
"yyyyMMddTHHmmssfffffff",
"yyyy-MM-dd",
"yy-MM-dd",
"yyyyMMdd",
"HH:mm:ss",
"THHmmss"

评论