Haskell笔记(一)

阅读和代码摘录自:http://learnyouahaskell.com

1.infix

div 92 10

也可写成

92 `div` 10

2.List

"hello" is just syntactic sugar for ['h','e','l','l','o']. Because strings are lists, we can use list functions on them, which is really handy.

两个list相加

ghci> [1,2,3,4] ++ [9,10,11,12]  
[1,2,3,4,9,10,11,12]
ghci> 'A':" SMALL CAT"  
"A SMALL CAT"  
ghci> 5:[1,2,3,4,5]  
[5,1,2,3,4,5]  

获取列表中某项,使用!!

ghci> "Steve Buscemi" !! 6  
'B'  
ghci> [9.4,33.2,96.2,11.2,23.25] !! 1  
33.2  

对列表的一下基本操作有head(返回第一个元素)、tail(返回除了第一个元素外的所有元素)、last(返回最后一个元素)、init(返回除了最后一个元素外的所有元素),length、null(返回True或False)、reverse、take、drop、elem、sum用法是

ghci> head [5,4,3,2,1]  
5 
Prelude> let a = ['a', 'b', 'd', 'e']
Prelude> take 2 a
"ab"
Prelude> a
"abde"
Prelude> drop 1 a
"bde"
Prelude> a
"abde"
Prelude> 'a' `elem` a
True
Prelude> 'z' `elem` a
False
Prelude> sum [5, 2, 1]
8

Haskell笔记(一) 请给我一个数字1到20的列表。

Prelude> [1..20]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
Prelude> [1,4..20]
[1,4,7,10,13,16,19]

然后是一些神奇的东西。

cycle:指定一个列表然后会无限循环,比如 cycle [1, 2, 3],列表就是[1, 2, 3, 1, 2, 3, 1, 2, 3…………]

repeat:takes an element and produces an infinite list of just that element.

3.comprehension

Prelude> [ x*2 | x <- [1..10] ]
[2,4,6,8,10,12,14,16,18,20]

x is drawn from [1..10]。

继续添加条件

ghci> [ x | x <- [10..20], x /= 13, x /= 15, x /= 19]  
[10,11,12,14,16,17,18,20]  

请给我写一个计算list长度的函数

Prelude> let mylength xs = sum[ 1 | _ <- xs ]
Prelude> mylength "sadfewsdf"
9
Prelude> mylength [1,2,3,4,5,6]
6
Prelude>

那个‘ _ <- xs’里的‘ _’到底是什么东西呢?直接引用好了:

_ means that we don't care what we'll draw from the list anyway so instead of writing a variable name that we'll never use, we just write _. This function replaces every element of a list with 1 and then sums that up. This means that the resulting sum will be the length of our list.
还记得sum的用法吧,

Prelude> sum [1,2,5]
8

sum需要一个列表, [ 1 | _ <- xs ]返回一个列表,而这个列表是什么呢? 可以再分解一下来看问题:

Prelude> [ 1 | _ <- "abcd" ]
[1,1,1,1]
Prelude> sum [1, 1, 1, 1]
4

那么现在就不难理解了。

4.Tuples

fst:返回pair的第一个元素

snd:返回pair的第二个元素

zip:两个列表间相互结合成新列表

Prelude> fst ("wow", 9)
"wow"
Prelude> snd ('d', [1, 2, 3])
[1,2,3]
Prelude> zip [1, 2, 3] ['a', 'd', 'c', 'd', 'e']
[(1,'a'),(2,'d'),(3,'c')]

5.Types and Typeclasses

:t可以用来查看类型

ghci> :t 'a'  
'a' :: Char  
ghci> :t True  
True :: Bool  
ghci> :t "HELLO!"  
"HELLO!" :: [Char]  
ghci> :t (True, 'a')  
(True, 'a') :: (Bool, Char)  
ghci> :t 4 == 5  
4 == 5 :: Bool  

:: is read as "has type of"

函数也是有类型,也可应通过:t来查看,基本类型Int、Integer、Float、Double、Bool、Char。

Prelude> let removeNonUppercase st = [ c | c <- st, c `elem` ['A'..'Z'] ]
Prelude> removeNonUppercase "aAbBCCd"
"ABCC"
Prelude> :t removeNonUppercase
removeNonUppercase :: [Char] -> [Char]

果断引用原文:

removeNonUppercase has a type of [Char] -> [Char], meaning that it maps from a string to a string. That's because it takes one string as a parameter and returns another as a result. The [Char] type is synonymous with String so it's clearer if we write removeNonUppercase :: String -> String.
那么下面这个函数呢

Prelude> let addThree x y z = x + y + z
Prelude> addThree 1 2 3
6
Prelude> :t addThree
addThree :: Num a => a -> a -> a -> a

恩.. 好像跟教程有点不一样。 先跳过好了。
还记得 head函数吗?他返回任意类型列表的第一个元素,那么这个函数是什么类型呢?

Prelude> :t head
head :: [a] -> a

出来一个a,它是一个类型吗?还记得之前提到过类型的首字母是大写的(Int、Float、Bool…),所以a不是一个类型,它实际上是一个type variable 有种虽不明但觉厉的感觉了吧。 意味着a能够是任意类型。

This is much like generics in other languages, only in Haskell it's much more powerful because it allows us to easily write very general functions if they don't use any specific behavior of the types in them. Functions that have type variables are called polymorphic functions.
再看一个例子:

Prelude> :t fst
fst :: (a, b) -> a

b也是一个type variable。

再来个例子:

Prelude> :t (==)
(==) :: Eq a => a -> a -> Bool

神奇符号 =>出现了。还是果断直接引用教程:

Everything before the => symbol is called a class constraint. We can read the previous type declaration like this: the equality function takes any two values that are of the same type and returns a Bool. The type of those two values must be a member of the Eq class (this was the class constraint).
所以下面的语句是会错误的:

Prelude> 1 == "as"

<interactive>:1:1:
    No instance for (Num [Char])
      arising from the literal `1'
    Possible fix: add an instance declaration for (Num [Char])
    In the first argument of `(==)', namely `1'
    In the expression: 1 == "as"
    In an equation for `it': it = 1 == "as"

因为1和"as"是不同的类型,而==函数需要类型相等这种class constraint(类型约束?)。还有段文字比较重要:

The Eq typeclass provides an interface for testing for equality. Any type where it makes sense to test for equality between two values of that type should be a member of the Eq class. All standard Haskell types except for IO (the type for dealing with input and output) and functions are a part of the Eq typeclass.
read:这个函数主要是读入一个字符串然后返回一个Read类型。

Prelude> :t read
read :: Read a => String -> a
Prelude> read "12" - 2
10

拆开看就是

Prelude> (read "12") - 2
10

至于Read类型是啥,我不是很清楚。
假如这样输入:

Prelude> read "4"

<interactive>:1:1:
    Ambiguous type variable `a0' in the constraint:
      (Read a0) arising from a use of `read'
    Probable fix: add a type signature that fixes these type variable(s)
    In the expression: read "4"
    In an equation for `it': it = read "4"

GHCI告诉我们它不知道该返回什么。再看一下read函数的类型,它返回的是一个Read,

See? It returns a type that's part of Read but if we don't try to use it in some way later, it has no way of knowing which type.That's why we can use explicit type annotations. Type annotations are a way of explicitly saying what the type of an expression should be. We do that by adding :: at the end of the expression and then specifying a type
Prelude> read "5" :: Int
5
Prelude> (read "5" :: Float) * 4
20.0

关于Typeclasses的重要说明

A typeclass is a sort of interface that defines some behavior. If a type is a part of a typeclass, that means that it supports and implements the behavior the typeclass describes. A lot of people coming from OOP get confused by typeclasses because they think they are like classes in object oriented languages. Well, they're not. You can think of them kind of as Java interfaces, only better.
基本的typeclasses:

Eq、Ord、Show、Read、Enum、Bounded、Num、Integral、Floating。

你可能感兴趣的:(Haskell笔记(一))