Facebook Twitter LinkedIn E-mail
magnify
formats

F#开发教程(3):函数化编程(二)

递归函数

递归函数在定义时可以调用自身。递归函数在函数化编程中经常起到指令化编程中循环语句的作用。一般认为使用算法使用递归函数比使用循环语句更容易让人理解。
在F#,需要使用rec来修饰所定义的函数为一递归函数。

> 
let rec fib x =
-   match x with
-    | 1 -> 1
-    | 2 -> 1
-    | x -> fib (x-1) + fib(x-2);;

val fib : x:int -> int

fib 11;;

val it : int = 89

可以看出在F#定义递归函数和定义对应的数学递推公式在书写上非常类似,因此也非常容易理解。在编写递归函数时需要注意的是递归函数终止条件的定义,定义不好,可能会造成递归函数永无止境。本例斐波拉契数列初始条件为1,2时的结果。

这里的match 关键字定义一个“模式匹配”,我们将在后面进一步介绍。

操作符(运算符)

和C#一样,F#支持大量的操作符,通常分为两类
前缀操作符 操作符在前,一个操作数,比如 负号操作符 -3
中缀操作符 操作符在两个操作数之间,比如 加号 3 + 4
F#也支持操作符重载,也允许你定义新的操作符,和C#操作符不同是,F#需要被操作数为同一数据类型。
操作符所起的作用和函数非常类似,但操作符本身不能作为数值来看待,因此不可以直接作为参数传递。但如果你需要把操作符作为参数或作为数值来对待,可以使用括号,操作符带()号后就可以作为数值看待,因此也可以作为参数传递。
比如

> 
> let res = (+) 1 1;;

val res : int = 2

let add = (+)

你可以使用下面的符号来定义一个操作符

!%&*+-./< =>@^|~

这些符号中只有几个可以作为前缀操作符,具体可以参考相关文档。比如!(除!=之外)可以做为前缀操作符。

 
Tags:
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
F#开发教程(3):函数化编程(二)已关闭评论  comments 
formats

F#开发教程(2):函数化编程(一)

在纯函数化编程语言中,所有一切包括函数都是一个数值。尽管F#不是一个纯粹的函数化编程语言,但它鼓励你使用函数化风格来编写代码。也就是说尽量使用表达式或是计算来返回结果,而少使用有副作用的语句。

字面量

字面量代表了一些常数,它们是构成计算的基本组成部分。F#支持多种不同类型的字面量。它通常使用后缀来代表不同数据类型。

比如字符类型字面量
“Hello\t “,”World\n”
@”c:\dir\fs”, @””””
“””She said “Hello”””” 使用三个”””来定义字符串,中间的”无需要转义。

“bytesbytesbytes”B byte 数组
‘c’ char单个字符
true, false bool 布尔类型
0x22 十六进制整数
0o42 八进制整数
0b10010 二进制整数
34y 带符号字节
34uy 无符号字节
34s int16整数
34us uint16整数
34l int/int32整数
34ul uint32整数
34n nativeint整数
34un unativeint整数
34L int64整数
34UL uint64整数
3.0F, 3.0f float32浮点数
3.0 float浮点数
3474262622571I bigint大整数
474262612536171N bignum大整数

比如


> let bytes ="0123456789"B;;

val bytes : byte [] =
  [|48uy; 49uy; 50uy; 51uy; 52uy; 53uy; 54uy; 55uy; 56uy; 57uy|]

> 

匿名函数

在F#匿名函数使用fun来定义,函数的参数由空格分开,函数名称和函数体直接使用->隔开
例如


f x y -> x + y

匿名函数也称为lambda函数或简称为lambda.

标识符和let绑定

标识符是F#用来给数值命名,使用let关键字来把一个数值和标识符绑定。 比如


let x = 3 + 4

看起来这有点和其它语言的赋值语句查不多,x这里看起来和其它语句中变量名差不多。但关键的一点区别是在纯函数化编程中一旦标识符和数值绑定后,不可重新赋值。因此F#我们使用标识符而不使用变量名这个定义。在某些情况下,你可以重新赋值给标识符,此时需要使用mutable来特别修饰。

函数定义也是一个数值,因此标识符也可以和函数定义绑定。比如

let myAdd = fun x y = x + y

而在通常情况想,我们定义函数时会给函数一个名称,F# 使用了一个简化的语法来定义一个有名称的函数,比如

let raisePowerTwo x = x ** 2.0

上面第一个名称raisePowerTwo 为函数名,x为函数的一个参数。

标识符命名

和其它程序语言类型,标识符名称需要满足一个规则,通常标识符以字母或是下划线_开始。后面可以是数字字母和单引号’。通常关键字不可作为标识符。F#支持Unicode做为标识符。如果使用关键字或是带空格的标志符,可以使用双反引号“来分隔标志符,比如

let ``more? `` = true
let ``class`` = "style"

作用域

标志符具有作用域的属性,标识符作用域和其它编程语言类似。但需要注意的,缩进在F#具有语法意义,同等级的缩进定义了一个作用域。和C#,每缩进一级相当于定义一个新的{}语句块。在F#不可以使用制表符来缩进,你可以重新定义制表符为多个空格(通常为4个空格)来缩进代码。
如果在嵌套内部函数中引用(捕获)外层定义的标识符,该标志符的生命周期可能在离开定义该标识符的作用域外还可以在嵌套内部函数(闭包)中继续存在。

 
Tags:
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
F#开发教程(2):函数化编程(一)已关闭评论  comments 
formats

F#开发教程(1):概述

函数化编程

F#是一种函数优先的强类型语言,但它支持类型推断(type inference),一般不需要在代码在明确指明变量,数值,参数的类型,编译器可以根据上下文推断出变量,数值,参数的类型。当然你愿意的话,也可以指明变量,数值,参数的类型。
F#是一个以表达式为主的语言,程序运行时以一种比较积极的方式来演算这些表达式(eager evaluation).F#中所有的语句包括if表达式,try表达式和循环都可以返回某种类型的值。那些不需要返回值的函数和表达式返回unit类型的值。F#使用let来绑定一个值到一个名称(别的语言中一般称为变量,F#如果使用变量有些名不符实,F#let一般绑定的值是不可以更改的非变量)。
比如

let x = 3 + 4

绑定x到整数7.

F#使用type来定义新的类型F#,对于函数化编程,F#支持元组(tuple),记录(record),联合(discriminated union),列表(list)以及可选(option)类型。
元组(tuple)类型代表有n个数值的集合数据类型,比如一个三元组可以代表(A,B,C),其中A,B,C可以代表任何类型的数据。
记录(record)类型有点类似C#中的结构类型,和元组相比,记录类型的数据成员可以有名字,比如{ Name:string;Age:int}, F#使用with来创建一个记录的拷贝,比如 { r with Name =”CD”}。
可区分联合(discriminated union)或者简称为联合类型类似为C中的联合类型,但它为一类型安全的联合类型。比如

type A =
  | UnionCaseX of string
  | UnionCaseY of int

这个联合类型的值可以为两个类型其中任意一种。
列表(list)类型为一不可以更改链表结构,它可以使用head::tail来表示。::为列表合并操作符。列表页使用[item1;item2;item3 …]来定义,[]为空表。
可选(option)类型为一联合类型,一个类型为None,表示没有值,另外一个类型为Some(x),其中x可以为任意类型的数据。
F#的类型可以为通用类型。
F#支持lambda表示式,支持闭包(closure)。F#中所有函数类型为一等公民并且是不可以更改的。函数支持柯里化(curried,部分函数),由于函数类型为一等公民,因此和其它基本类型(int,string等)一样可以作为其它函数的参数,和其它函数化编程语言一样,F#支持使用< <,>>来构成组合函数。
F#支持序列表达式来通过代码生成定义序列 seq {…},列表 list[…]和数组 [|…|]。比如

 seq { for b in 0 .. 25 do
           if b  < 15 then
               yield b*b}

构造0-14的平方。序列(数列)为一构造器(描述数列中元素的特征),序列中的值在有需要是才生成。这个数组和列表不同。因此序列可以用来表示无限数列。
F#也支持模式匹配(pattern matching),使用模式匹配可以把数值绑定到名称。模式匹配功能异常强大。

指令性编程(面向过程编程)

  • F#的指令性编程包括
  • for 循环指令
  • while 循环指令
  • 使用[|…|]构造数组
  • 使用dict […] 或者 System.Collections.Generic.Dictionary构造哈希表

数值或记录类型如果需要支持更改 (变量),可以使用mutable 来修饰。比如

 let mutable x = 1
 x <- 3

 

面向对象编程

F#和其它CLI语言,支持面向对象编程,F#支持面向对象的表达式种类如下:

  • 使用.来引用对象的属性或函数,比如 x.Name
  • 对象表达式,比如 {new obj() with member x.ToString() = “hello” })
  • 对象构造函数
  • 类型测试 ,比如 x : ? string
  • 类型强制转换 比如 x :?> string
  • 命名参数
  • 命名setter ,比如 new Form (Text =”hello”)
  • 可选参数 比如 x.Method (OptionalArg =1)

F#的对象类型type定义可以用来定义类似C#中class,struct, interface,enum ,delegate类型,比如下面代码使用type定义一个class

  type Person (name :string, age :int) = 
      member x.Name = name
      member x.Age = age

 

此外F#支持异步,并行编程,命名空间(namespace),模块定义(module),可以定义数值使用的“量词”(units of measure) 等等。
最后需要特别说明的是F#代码空格是有意义的,缩进代表了语句的层次关系,它通常不使用{},;来分隔语句。

 
Tags:
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
F#开发教程(1):概述已关闭评论  comments 
formats

F#开发教程

有快两年时间没怎么更新博客了,最近决定重新开始更新博客,一时也没想好写哪个方面的比较好,想起之前写过Scala教程,最近偶然的接触了F#,和Scala语言非常类似,就如同C#和Java也比较类似。因为也是刚开始接触F#,还是以翻译参考为主,这个系列主要参考由Apress 出版Robert Pickering编写的《开始F#4.0编程》第二版的第三章到第七章的内容。学完这几章也就可以算是初窥F#门墙。

F#是由微软发展的为微软.NET语言提供运行环境的程序设计语言,是函数编程语言FP,Functional Programming),函数编程语言最重要的基础是Lambda Calculus。它是基于OCaml的,而OCaml是基于ML函数程序语言。有时F#和OCaml的程序是可以交互编译的。

F#已经接近成熟,支持高阶函数、柯里化惰性求值、Continuations、模式匹配、闭包、列表处理和元编程。这是一个用于显示.NET在不同编程语言间互通的程序设计,可以被.NET中的任意其它代码编译和调用。

目前F#  版本为4.0.1 夸平台支持。支持交互式运行。

F#通常在以下几个方面使用 –

  • 制定科学模型
  • 数学解题
  • 人工智能的研究工作
  • 金融建模
  • 平面设计
  • CPU设计
  • 编译器编程
  • 电信

此外,Xamarin  也支持使用F# 开发Android,iOS ,Windows 手机应用。

 
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
F#开发教程已关闭评论  comments 
formats

摩尔斯电码工具软件Morse Code Toolkit

摩尔斯电码英语:Morse code)是一种时通时断的信号代码,通过不同的排列顺序来表达不同的英文字母数字标点符号。是由美国人萨缪尔·摩尔斯在1836年发明。

摩尔斯电码是一种早期的数字化通信形式,但是它不同于现代只使用0和1两种状态的二进制代码,它的代码包括五种:

  1. 点(.)
  2. 划(-)
  3. 每个字符间短的停顿(在点和划之间的停顿)
  4. 每个词之间中等的停顿
  5. 以及句子之间长的停顿

Morse Code Toolkit  是一款Android工具软件,可以帮助你在公车上无聊时打发时间,学习Morse电码 🙂

Morse_Code_Toolkit_-_Android_Apps_on_Google_Play

 
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
摩尔斯电码工具软件Morse Code Toolkit已关闭评论  comments 
formats

引路蜂游戏编程指南

Raindrop

Guidebee Android Game Engine – RainDrop Demo To use guidebee android game engine in your project in your build.gradle

add the following

dependencies {
    ...
    compile 'com.guidebee:game-engine:0.9.8'
}

Mario collect coins

Download

Guidebee Android Game Engine Tutorials

  1. Android Gradle Project
  2. Basics
  3. Packages
  4. Game Logic
  5. Basic Graphics
  6. Texture & TextureRegion
  7. TextureAtlas
  8. Handling Input and On Screen Game Pad
  9. Sound and Music
  10. Scenery and TiledMap
  11. SVG Image and Unmanaged Assets
  12. Collision Detection
  13. Microedition Game API
  14. Bring Physics to your Game World
  15. UI Components and HUD Components
  16. Camera and Viewport basics

Box2D

To use guidebee android game engine in your project in your build.gradle

add the following

dependencies {
    ...
    compile 'com.guidebee:game-engine:0.9.9'
}

Mario collect coins

Download

Guidebee Android Game Engine Box2D Tutorials

  1. Introduction
  2. Basic Concepts
  3. Control Player
  4. Body Types
  5. Shape Types
  6. Apply Forces and Impulses to Bodies
  7. Collision Detection and Collision Filter
  8. Sensors
  9. Ray Casts
  10. Joints
  11. More on Bodies
  12. The world
 
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
引路蜂游戏编程指南已关闭评论  comments