F# 学习笔记 1 基础学习

F#...函数式编程语言,每个表达式都是一个函数式的。function is values。

printf 方法 with %A pattern to output them to the console.

%A可以显示任何类型,类似于c#中的ToString 。

也可以使用print_any and any_to_string方法。

printf_string :打印一个string类型

printf_int:打印一个int类型。

...


1.values and Function:

sample:

#light
let n = 10
let add a b = a + b
let addFour = add 4
let result = addFour n
printfn "result = %i" result

------------

result=14

不必一次传入所有的参数,因为一个方法就是一个值,所以,在addFour中只传入一个参数,当add方法没有收到所有的参数,它会产生一个新的方法,并wait,直到另一个参数传来然后返回一个value。

如果一个方法必须输入两个参数,可以使用let add (a,b) = a+b的方式,这样add方法必须要输入两个参数了。


2.在f#中方法体都是使用缩进来判断的。如下:

#light
let halfWay a b =
let dif = b - a
let mid = dif / 2
mid + a
printfn "(halfWay 5 11) = %i" (halfWay 5 11)
printfn "(halfWay 11 5) = %i" (halfWay 11 5)

--------

(halfWay 5 11) = 8
(halfWay 11 5) = 8

#light: 必须放在f#文件的最开头,这个表示可以使f#识别空格等,否则必须要输入begin,in等等的一些关键字了。

halfWay 方法,有两个参数,a,b,并返回一个value.

3.变量作用域。

在f#中,变量的作用域,方法中,方法中的定义的变量在方法结束后,失去作用。

#light
let defineMessage() =
let message = "Help me"
print_endline message
print_endline message
--error.

#light
let mathsPuzzle() =
print_string "Enter day of the month on which you were born: "
let input = read_int ()
let x = input * 4 // Multiply it by 4
let x = x + 13 // Add 13
let x = x * 25 // Multiply the result by 25
let x = x - 200 // Subtract 200
print_string "Enter number of the month you were born: "
let input = read_int ()
let x = x + input

let x = x * 2 // Multiply by 2
let x = x - 40 // Subtract 40
let x = x * 50 // Multiply the result by 50
print_string "Enter last two digits of the year of your birth: "
let input = read_int ()
let x = x + input
let x = x - 10500 // Finally, subtract 10,500
printf "Date of birth (ddmmyy): %i" x
mathsPuzzle()
在方法中,可以重复定义一个变量并使用,而不用使用一个中间变量。


4.递归

递归就是自己调用自己咯..在f#中,使用在let之后使用关键字rec,表示方法可以被自己调用。

#light
let rec fib x =
match x with
| 1 -> 1
| 2 -> 1
| x -> fib (x - 1) + fib (x - 2)
printfn "(fib 2) = %i" (fib 2)
printfn "(fib 6) = %i" (fib 6)
printfn "(fib 11) = %i" (fib 11)

当然使用递归方法的时候要小心,否则进入死循环中了哦。这样会消耗掉你系统资源,知道throw System.StackOverflowException.

5.匿名Function

在f#中提供另外一种方式定义方法,使用fun 关键字和function关键字。
#light
let x = (fun x y -> x + y) 1 2

let x1 = (function x -> function y -> x + y) 1 2
let x2 = (function (x, y) -> x + y) (1, 2)

6.Operators

F# has two different kinds of operators, prefix and infix; a prefix operator is an operator
that takes one operand, and an infix operator takes two or more. Prefix operators appear
before their operand, whereas infix operators appear between the first two operands

F#可以重新定义操作符。例如

#light
let (+) a b = a - b
print_int (1 + 1)

User-defined (custom) operators must be nonalphanumeric and can be a single character
or a group of characters. You can use the following characters in custom operators:
!$%&*+-./<=>?@^|~
:

自定义操作符,可以是上面第一行中任何一个字符开始。例如:

#light
let ( +:* ) a b = (a + b) * a * b
printfn "(1 +:* 2) = %i" (1 +:* 2)

---

(1 +:* 2) = 6

7.List

在F#中可以使用::,将一个值插入到list的前面,如:

#light
let emptyList = []
let oneItem = "one " :: []
let twoItem = "one " :: "two " :: []

list的定义是一个大括号和使用';'分隔

#light
let shortHand = ["apples "; "pairs "]

list中可以使用@ 将两个list连接起来。

let twoLists = ["one, "; "two, "] @ ["buckle "; "my "; "shoe "]

list中的元素必须是相同类型的,如果要往twoLists中插入一个int的类型,编译的时候会有Error。

如果要在list中放入不同类型的元素,可以使用obj,如下:

let objList = [box 1; box 2.0; box "three"]

sample:

#light
#nowarn"62"
open System


let emptyList = []
let oneItem = "one " :: []
let twoItem = "one " :: "two " :: []
let shortHand = ["apples "; "pairs "]
let twoLists = ["one, "; "two, "] @ ["buckle "; "my "; "shoe "]
let objList = [box 1; box 2.0; box "three"]
let printList l =
List.iter print_string l
print_newline()


let main() =
printList emptyList
printList oneItem
printList twoItem
printList shortHand
printList twoLists
for x in objList do
print_any x
print_char ' '
print_newline()

main()

Console.ReadKey()

----

one
one two
apples pairs
one, two, buckle my shoe
1 2.000000 "three"


List创建后是不可改变的,但是可以给一个新的list复制,也可以使用List.rev 将list中的元素颠倒并产生一个新的list。如下:

#light
let one = ["one "]
let two = "two " :: one
let three = "three " :: two
let rightWayRound = List.rev three
let printList l =
List.iter print_string l
print_newline()
let main() =
printList one
printList two
printList three
printList rightWayRound
main()

-----

one
two one
three two one
one two three

--

List.hd:取出List中的第一个元素。

List.tl :取出剩下的元素。
#light
#nowarn"62"
open System


let listOfList = [[2; 3; 5]; [7; 11; 13]; [17; 19; 23; 29]]
let rec concatList l =
if List.nonempty l then
let head = List.hd l
let tail = List.tl l
head @ (concatList tail)
else
[]
let primes = concatList listOfList
print_any primes


Console.ReadKey()


List.iter : List的方法,有两个参数,第一个是一个方法,用于定义要应用每个list元素的方法,第二个参数要应用的list。其实就是一个for loop的简单写法。



8.List Comprehensions

.. :从第一个数字,+1,知道=最后一个数字。

#light
let numericList = [ 0 .. 9 ]
let alpherSeq = { 'A' .. 'Z' }
printfn "%A" numericList
printfn "%A" alpherSeq


The results of this example are as follows:
[0; 1; 2; 3; 4; 5; 6; 7; 8; 9]
seq ['A'; 'B'; 'C'; 'D'; ...]

list 还可以定义步长的方式定义一个list,使用两个.

如:

#light
let multiplesOfThree = [ 0 .. 3 .. 30 ]
let revNumericSeq = [ 9 .. -1 .. 0 ]
printfn "%A" multiplesOfThree
printfn "%A" revNumericSeq

[0; 3; 6; 9; 12; 15; 18; 21; 24; 27; 30]
[9; 8; 7; 6; 5; 4; 3; 2; 1; 0]

也可以定义一个循环来定义一个list,如:

#light
let squares =
{ for x in 1 .. 10 -> x * x }
print_any squares

9.流程控制

if ...then ....else....
#light
let result =
if System.DateTime.Now.Second % 2 = 0 then
"heads"
else
"tails"
print_string result

if 语句返回必须是相同的类型,如果要返回不同的类型,可以使用ojbect包装一下。

#light
let result =
if System.DateTime.Now.Second % 2 = 0 then
box "heads"
else
box false
print_any result






原文地址:https://www.cnblogs.com/zhucl1006/p/1268584.html