1.list:
列表构造:直接输入列表[1,2,3,4,5]
[1..5] 输出[1,2,3,4,5]
[1,3,…11] 输出[1,3,5,7,9,11] (构造等差数列)
[1..] 输出[1,2,3,……] (构造1到无穷大的无限列表)
[x*2 | x<-[1..10], mod x 2 == 1] 先构造列表[1..10],从中选出满足除2的余数
等于1的数[1,3,5,7,9],最后乘2,输出[2,6,10,14,18]
列表拼接:[1,2]++[3,4]++[5,6] 输出 [1,2,3,4,5,6]
1:[2,3,4] 输出[1,2,3,4] (将1拼接到数组前,注只能拼在前,不能拼在后 [2,3,4]:1 ×)
列表取值:take 3 [1,2,3,4,5] 输出 [1,2,3] (取列表前3个值)
drop 3 [1,2,3,4,5] 输出[4,5] (扔掉列表前3个值)
last [1,2,3,4,5] 输出[5] (取列表最后一个值)
init [1,2,3,4,5] 输出[1,2,3,4] (丢掉列表最后一个值)
elem 2 [1,2,3,4,5] 输出True (查看2是否在列表中)
[1,2,3,4,5] !! 2 输出3 (取列表索引为2的元素)
2.string:“Hello World”就构造了一个字符串,其本质是char list,所以可以用所有list的方式操作string
3.函数调用:像前面用到的take 3 [1,2,3,4,5]就是一个函数调用,调用了take函数,take函数接收两个参数,第一个参数是数字,第二个参数是数组,多个参数以空格隔开,然后这个函数会输出一个数组
4.函数定义:distance x y = sqrt(x^2 + y^2)
定义了函数distance, 接收两个参数,进行后面的运算后,返回x和y的距离(这里sqrt也是调用了sqrt函数,去计算平方根,该函数接收一个参数)
所以要调用该函数就只用输入distance 3 4 输出5
另:若只传一个参数,输入distance 3,则返回的是sqrt(3^2 + y^2)这个函数,即你可以将distance 3当成函数func y = sqrt(3^2 + y^2)使用,f = distance 3,则f 4输出5
定义分段函数:
:{
relu x
| x > 0 = x
| otherwise = 0
:}
relu 10 输出 10 relu(-10) 输出0
5.模式匹配:
:{
func [] = "empty"
func [x] = "only one"
func [x,y] = "two element"
func (x:y:_) = "more than two"
:}
输入func [] 输出“empty”
输入func [3] 输出 “only one”
输入 func [1,2] 输出 “two element”
输入 func [1,2,3] 输出 “more than two”
注意:对于输入的匹配是从上到下的,如果将最后一条放到第一条,则输入[1,2]会输出“more than two”,因为(x:y:_)意思是数组中除了有x和y两个数字外,还会有任意的东西,包括空,所以[1,2]会直接匹配(x:y:_),就不会继续往后匹配了
另:模式匹配的所有输出都要是相同类型的, 要么像这里全部输出字符串,要么就全部输出的是数字,要么全部输出的都是数组
上面模式匹配可以写成如下等价的case形式:
:{
func xs = case xs of [] -> "empty"
[x] -> "only one"
[x,y] -> "two element"
(x:y:_) -> "more than two"
:}
表示如果接收到的数组xs是空的话则输出"empty",是[x]的话输出"only one",是[x,y]的话..
6.递归:
求数组中的最大值
:{
max_list [x] = x
max_list xxs@(x:xs) = max x (max_list xs)
:}
(这里xxs@的意思是,为数组(x:xs)取名为xxs,这样如果等号右边要用到这个数组可以直接用xxs(虽然这里并没用到..))
第一行是匹配数组中只有一个数时,第二行是将数组分割成了第一个数x和剩下的所有xs(xs可以为空,也就是说数组中只有一个数时也是可以匹配到这个的,但是因为放在了第二行,所以这个只能匹配到大于一个数的情况)
7.map:这个函数接收两个参数,第一个参数接收一个函数,第二个参数接收一个list,map函数会对list中 的每一个元素调用你传进去的函数,然后输出list
如:map (*3) [1,2,3,4,5] 输出 [3,6,9,12,15] (*3,<3这些也是函数)
8.filter:和map一样接收一个函数和一个list作为参数,但是传进去的这个函数是能返回True或者False的函数,filter也会对list中的每个元素调用传进去的函数,并且最后输出会返回True的元素组成的数组。
如:filter (<3) [1,2,3,4,5] 输出[1,2]
9.foldl:这个函数接收三个参数,第一个参数是一个接收两个参数的函数,第二个参数是一个数字,第三个参数是一个list
foldl (\x y -> x + y) 4 [3,2,1] (中间传进去的是Haskell的lambda表达式,该函数接收两个参数x和y返回x+y,lambda表达式就是一个函数,就是在懒得给函数命名的时候,可以直接这样写)
上面的调用就等于 foldl (+) 4 [3,2,1]
那么fold函数会做这样的操作:4 + 3 + 2 + 1 = 10,即用中间的函数将数字和数组给串起来,其严格的将是4和3传入函数(+)中,然后将输出的值7和数组中的2再传入函数(+)中,再将输出的值9和数组中的1传入函数(+)中,最后输出10
10.函数应用符 $ :签名为 (a -> b) -> a -> b, 例如对于函数f x = x + 1,怎么f 3相当于 f $ 3,即把符号又变的作为参数传给符号左边的函数。那这个符号意义在哪里呢?假设还有函数g x y = x + y,那么g 3 (f 1)就是给1加上1后再和3相加,结果为5,可以改写成g 3 $ f 1,这样就不需要加括号了,$会把它右边的算出来后作为参数传给左边的g 3函数