haskell 类型

1) haskell是静态强类型语言,一切皆有类型

2) haskell支持类型推导


In [6]:
-- ghci中使用 `:t` 查看类型
-- 类型使用大写字母开头

In [1]:
:t 'a'


'a' :: Char

In [2]:
:t True


True :: Bool

In [3]:
:t "hello!"


"hello!" :: [Char]

In [4]:
:t (True, 'a')


(True, 'a') :: (Bool, Char)

In [5]:
:t 4 == 5


4 == 5 :: Bool

In [7]:
-- 函数也有类型
removeNonUppercase :: [Char] -> [Char]
let removeNonUppercase st = [c | c <- st, c `elem` ['A'..'Z']]


Use String
Found:
[Char] -> [Char]
Why Not:
String -> String
The type signature for ‘removeNonUppercase’ lacks an accompanying binding

In [8]:
-- 多参函数类型定义, 按科里化的方式来读
addThree :: Int -> Int -> Int -> Int
addThree x y z = x + y + z

In [9]:
:t addThree


addThree :: Int -> Int -> Int -> Int

In [10]:
-- Int为有界整数,Integer为无界整数
factorial :: Integer -> Integer
factorial n = product [1..n]

In [11]:
factorial 50


30414093201713378043612608166064768844377641568960512000000000000

In [12]:
-- Float和Doubel表示浮点数
-- Char表示一个Unicode字符
-- Bool只有True/False
-- tuple最大长度为62
circumference :: Float -> Float
circumference r = 2 * pi * r

In [13]:
circumference 4.0


25.132742

In [14]:
circumference' :: Double -> Double
circumference' r = 2 * pi * r
circumference' 4.0


25.132741228718345

In [15]:
-- 使用小写变量来表示类型变量,用来支持多态函数
-- 类似范型
:t fst


fst :: forall a b. (a, b) -> a

In [16]:
-- 类型类是定义行为的接口,类似java interface

In [17]:
:t (==)


(==) :: forall a. Eq a => a -> a -> Bool

In [18]:
-- 全部为特殊字符的函数默认为中缀函数
-- 要变为前缀需要使用 `()`, 如 (==), (+)

In [19]:
-- Eq类型需要实现 `==` `/=`

In [20]:
5 == 5


True

In [21]:
5 /= 5


False

In [22]:
'a' == 'a'


True

In [23]:
"Ho Ho" == "Ho Ho"


True

In [24]:
-- Ord类型用于比较大小
-- > < >= <=
-- compare函数类型ruby太空船操作
"Abrakadbra" < "zebra"


True

In [25]:
5 >= 2


True

In [26]:
5 `compare` 3


GT

In [27]:
'b' > 'a'


True

In [28]:
-- show类型类型python里__str__
show 3


"3"

In [29]:
show 5.334


"5.334"

In [30]:
show True


"True"

In [31]:
-- read类型是show的反向.eval

In [32]:
read "True" || False


True

In [33]:
read "8.2" + 3.8


12.0

In [35]:
read "5" - 2


3

In [36]:
read "[1,2,3,4]" ++ [3]


[1,2,3,4,3]

In [38]:
-- this would raise, 需要通过类型推倒或现式指定类型
-- read "4"
:t read


read :: forall a. Read a => String -> a

In [39]:
read "5" :: Int


5

In [40]:
read "5" :: Float


5.0

In [41]:
(read "5" :: Float) * 4


20.0

In [42]:
read "[1,2,3,4]" :: [Int]


[1,2,3,4]

In [43]:
read "(3, 'a')" :: (Int, Char)


(3,'a')

In [44]:
-- Enum类型可以枚举,连续的.
-- 可以配合区间使用. 通过succ/pred获取后继和前趋.
['a'..'e']


"abcde"

In [46]:
[LT .. GT]


[LT,EQ,GT]

In [47]:
[3 .. 5]


[3,4,5]

In [48]:
succ 'B'


'C'

In [49]:
-- Bounded类型有上下界. 通过maxBound/minBound获取
minBound :: Int


The type signature for ‘minBound’ lacks an accompanying binding
(The type signature must be given where ‘minBound’ is declared)

In [50]:
maxBound :: Char


The type signature for ‘maxBound’ lacks an accompanying binding
(The type signature must be given where ‘maxBound’ is declared)

In [51]:
:t minBound


minBound :: forall a. Bounded a => a

In [52]:
-- 如果tuple里都是Bounded,那tuple也是Bounded

In [53]:
maxBounded :: (Bool, Int, Char)


The type signature for ‘maxBounded’ lacks an accompanying binding

In [59]:
-- Num类型是一个数值特征, 数值都是多态常量
:t 20


20 :: forall a. Num a => a

In [55]:
20 :: Int


20

In [56]:
20 :: Integer


20

In [58]:
20 :: Float


20.0

In [60]:
:t (*)


(*) :: forall a. Num a => a -> a -> a

In [61]:
-- 有时一个类型必须先实现某个类型类,才能实现另一个类型类