Haskell的基本语法和GHCi

时间:2022-04-10 16:08:44

1.注释

a) --这是一行注释

b) {-

这是一段注释

-}

2.表达式

a) 3 :: Float 标示是一个浮点数3,::起到说明类型的作用

b) sort [3,8,1,4] 是一次函数调用。Haskell中的函数调用不需要加括号,多个参数中间也不用加逗号。

c) Case Foo of True -> 1

  False ->2

最后一个表达式的值FooTrue时等于1,否则等于2

值得注意的是:if...then...elsecase...of...这些语句虽然在其他语言中作为控制结构的声明,在Haskell中大部分都是表达式。

d) 表达式就是有值的式子,Haskell和大多数编程语言一样,程序中包含表达式和声明两种;

3.声明

a) Haskell是一门强类型语言,所有表达式都有确定的类型,::可以用来手动标注类型

b) 绑定

addOne :: Int -> Int

addOne x = x +1

 

Welcome :: String

Welcone = “hello world”

上面语句中:welcome :: String 读作welcome的类型是String=则是把右侧的表达式绑定在左侧的名称上了,在代码其余地方,每当想要用”hello world”时使用wecome即可。

NOTEHaskell语言中一旦一个名字被绑定给了表达式(上述”hello world”也是表达式),这个名称包含的表达式就永远不会再变了,Haskell中不存在变量的概念,只存在绑定,任何时刻一个名称对应的表达式都是唯一确定的。

上述addOne 是一个函数绑定,与第二个不同,判断方法是=后有多个名称。

c) 作用域

X = 1

Let x = 2

In y = x --此处y == 2

Z = x --此处z ==1

d) 导入

Haskell会默认在所在模块导入一个叫Prelude的模块函数,包含了许多基本的函数(例如print)。Haskell中的许多重要模块(包括prelude)一起构成了base库,这套base库会随着Haskell编译器一起发行。所以只有有可以工作的GHC,就可以直接导入base中的所有模块

e) 牢记:

Haskell中没有变量和赋值,只有绑定,且一旦绑定不能改变

Haskell中没有条件、循环、分支等控制声明,条件和分支在Haskell中是表达式的一部分

 

4.函数

a) 函数分为普通函数和中缀函数两种。普通函数的调用方法就是函数跟上参数,中缀函数和算式中的加减乘除差不多:先写一个参数,再写函数,最后再跟上一个参数

想要把一个普通函数当成中缀函数使用,需要在函数两边加上``(注意是键盘左上角``,不是‘’)

想要把中缀函数当成普通函数使用,需要在中缀函数两边加上括号

Eg.

elem 3 [1,2,3]

--elem x xs 判断列表xs中是否出现了x

3 `elem` [1,2,3]

--普通函数以中缀函数的形式调用

Eg.

(+) 1.5 1.5

--等价于1.5 + 1.5

b) ::是类型说明函数,优先级最低

5.GHCi

a) GHCi身处在一个连续的运算过程中,后面的绑定可以覆盖前面的绑定,暂时记得在GHCi中绑定名称时,一定要在前面加上let就好:let xs = [2,3,4,5]

b) Haskell中,确定的类型首字母大写(例如FloatBool)代表常亮,而不确定的类型一般都随意用小写字母a,b,c。。。表示,代表类型变量。当然也可以用小写字母开头的单词表示类型变量。

c) 查询中缀函数&& 的信息:

:info && :t (&&)

d) 绑定中缀函数的方法:(以++++做平方和为例)

(++++) :: Int -> Int -> Int

x ++++ y = x^2 + y^2

或者

(++++) :: Int -> Int -> Int

(++++) x y = x^2 + y^2

但是在GHCi中必须加上let才能使

e) 一些初级函数:

!! :: [a] -> Int -> a

--取列表第n个元素(从0开始)

[1,3,4] !! 2

--3

 

head :: [a] -> a

tail :: [a] -> [a]

--取列表头和尾

init :: [a] -> [a]

last :: [a] ->a

--取列表始和末

null :: [a] -> Bool

--判断列表是否为空

 

length :: [a] -> length

求列表长度

 

Take 2 [1,2,3,4,5]

--[1,2]

--取列表前N个元素

 

reverse :: [a] -> [a]

--颠倒一个列表

 

elem ,notElem 判断元素是否在列表中

 

min,max --判断两个元素中最大/最小的那个

minmum,maxmum --判断列表中最大/最小的那个