vern@2012-09-23:/var% ls tags
haskell

学习haskell

先来个哈喽喔儿的:

main = putStrLn "Hello, World!"

main代表函数名,等号=代表函数的实现。函数的参数放在函数名main和等号=之间。

GHCi, version 7.4.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> :load foo.hs
[1 of 1] Compiling Main             ( foo.hs, interpreted )
Ok, modules loaded: Main.
*Main> main
Hello, World!

编辑好foo.hs,在ghci:load命令加载,简单,挺好。

head' :: [a] -> a
head' [] = error "中文?"
head' (x:xs) = x

第一行是声明函数head'的类型,包括函数的参数类型和返回值类型。函数名head后面的单引号是合法字符,双冒号::是函数声明的关键字,中括号[]表示一个列表(list),最后一个细箭头->之前的表示参数的类型,之后的表示返回值类型。
第二行是定义函数的一个实现,在函数名head'后面和等号=之前的,表示之前说的函数的参数,中括号[]表示一个列表,在这里,表示参数是一个空列表,那么,调用函数error,跟在后面的是他的参数。
第三行是定义函数的另一个实现,小括号()表示一种很难解释的叫做模式匹配的东东,其中冒号:前面的匹配参数(一个列表)的首个元素,后面的匹配剩下的所有元素。那么,直接返回首个元素。

*Main> head' [7, 1, 1, 8]
7

他实现了取一个列表的第一个元素的功能。函数定义了两次,执行的时候按编码的顺序依次执行。

len' :: [a] -> Int
len' [] = 0
len' (x:xs) = 1 + len' xs

递归函数,第一个定义是说,如果参数是一个空列表,那么,返回0。其他情况下,匹配参数(一个列表)的首个元素和剩余元素,用1加上用剩余元素作为参数的递归调用的返回值。

*Main> len' [7, 1, 1, 8]
4

他实现了计算一个列表长度的功能。

name' :: String -> String -> String
name' (x:xs) (y:ys) = [x] ++ ". " ++ [y]

第一行,最后一个细箭头之前的表示函数name的参数,有两个,表示两个String类型的参数。返回值的类型,也是String
第二行,分别匹配两个参数,每一个小括号,匹配对应的一个参数(一个String就是一个Char的列表),首个元素分别是xy,剩余元素分别是部分xsys

*Main> name' "Zhang" "San"
"Z. S"

他实现了输出两个字符串首字母的功能。

max' :: (Ord a) => [a] -> a
max' [] = error "null"
max' [x] = x
max' (x:xs) = if x >= max' xs
    then x
    else max' xs

第一行,中间小括号中的Ord表示一个类型类。类型类,很牛逼,是一个类型(已经熟知的整型、布尔型、字符型等)的类型(可判断类型可比较类型枚举类型等)。属于Ord类型类的类型,必须是可以比较大小的类型。
也就是,函数max'的参数,既然是一个列表[a],那么,列表里面的每个元素a的类型,必须是可以比较大小的类型(数字、字符串等)。
第二行,如果参数是空列表,报错。
第三行,如果参数是只有唯一一个元素的列表,直接返回这个元素。
第四行,先开始参数模式匹配,首个元素和剩余元素分别由xxs代表,如果首个元素大于等于用剩余元素作为参数的递归调用的返回值,那么直接返回当前首个元素,否则用剩余参数作为max'函数的参数继续递归调用。

max' :: (Ord a) => [a] -> a
max' [] = error "null"
max' [x] = x
max' (x:xs)
    | x >= max' xs = x
    | otherwise = max' xs

max'的另一种定义,用竖线'|',即门卫(guard),在函数进门之前判断参数,并根据不同的参数,进入不同的函数门。

*Main> max' [7, 1, 1, 8]
8

取出一个列表中值最大的一个元素:

入门阅读 LYAH(Learn You a Haskell for Great Good!),英文原版中文版初级实战