Haskell笔记1
来源:互联网 发布:软件代码保护 编辑:程序博客网 时间:2024/05/29 09:33
Haskell笔记1
1. 类型
类型
例
lists
ghci> head [1,2,3,4]1
ghci> head ['a','b','c']'a'
tuples
ghci> (1964, "Labyrinths")
(1964,"Labyrinths")
2. 函数
函数
例
take
ghci> take 2 [1,2,3,4,5]
[1,2]
drop
ghci> drop 3 [1,2,3,4,5]
[4,5]
fst
ghci> fst (1,'a')
1
snd
ghci> snd (1,'a')
'a'
head
ghci> head (drop 4 "azerty")
't'
lines
ghci> lines "the quick\nbrown fox\njumps"
["the quick","brown fox","jumps"]
null
ghci> :type null
null :: [a] -> Boolghci> :type (||)(||) :: Bool -> Bool -> Bool
mod
isOdd n = mod n 2 == 1
ghci> print (myDrop 2 "abcd")"cd"
last
ghci> last [1,2,3,4,5]
5
ghci> last "baz"
'z'
3. 逻辑语句
分支和循环
例
If..then..else
myDrop n xs = if n <= 0 || null xs
then xs
else myDrop (n - 1) (tail xs)
We'll refer to the expressions after the then and else keywords as “branches”. The branches must have the same types; the if expression will also have this type. An expression such as if True then 1 else "foo" has different types for its branches, so it is ill typed and will be rejected by a compiler or interpreter.
Recall that Haskell is an expression-oriented language. In an imperative language, it can make sense to omit the else branch from an if, because we're working with statements, not expressions. However, when we're working with expressions, an if that was missing an else wouldn't have a result or type if the predicate evaluated to False, so it would be nonsensical.
4. Ghci环境
函数
例子
:load
ghci> :load add.hs
[1 of 1] Compiling Main ( add.hs, interpreted )
Ok, modules loaded: Main.
:cd
ghci> :cd /tmp
:type
ghci> :type lines
lines :: String -> [String]
ghci> :type last
last :: [a] -> a
5. 其他
概念
解释
结合性
In Haskell, function application is left associative. This is best illustrated by example: the expression a b c d is equivalent to (((a b) c) d).
It's pretty clear that there's something going on with an Int and some lists, but why are there two -> symbols in the signature? Haskell groups this chain of arrows from right to left; that is, -> is right-associative. If we introduce parentheses, we can make it clearer how this type signature is interpreted.
等号
When you see an = symbol in Haskell code, it represents “meaning”: the name on the left is defined to be the expression on the right.
函数的纯洁性
A side effect introduces a dependency between the global state of the system and the behaviour of a function. For example, let's step away from Haskell for a moment and think about an imperative programming language. Consider a function that reads and returns the value of a global variable. If some other code can modify that global variable, then the result of a particular application of our function depends on the current value of the global variable. The function has a side effect, even though it never modifies the variable itself.
Side effects are essentially invisible inputs to, or outputs from, functions. In Haskell, the default is for functions to not have side effects: the result of a function depends only on the inputs that we explicitly provide. We call these functions pure; functions with side effects are impure.
If a function has side effects, we can tell by reading its type signature: the type of the function's result will begin with IO.
ghci> :type readFile
readFile :: FilePath -> IO String
imperative language
Python,perl
variable
In Haskell, a variable provides a way to give a name to an expression. Once a variable is bound to (i.e. associated with) a particular expression, its value does not change: we can always use the name of the variable instead of writing out the expression, and get the same result either way.
Polymorphism
When a function has type variables in its signature, indicating that some of its arguments can be of any type, we call the function polymorphic.
subtype polymorphism
Since Haskell isn't an object oriented language, it doesn't provide subtype polymorphism.
parametric polymorphism
This kind of polymorphism is called parametric polymorphism.
coercion polymorphism
Also common is coercion polymorphism, which allows a value of one type to be implicitly converted into a value of another type. Many languages provide some form of coercion polymorphism: one example is automatic conversion between integers and floating point numbers. Haskell deliberately avoids even this kind of simple automatic coercion.
type signature
We can now write a type signature for the myDrop function that we defined earlier.
-- file: ch02/myDrop.hs
myDrop :: Int -> [a] -> [a]
6. 高级
概念
解释
Lazy evaluation
In Haskell, the subexpression 1 + 2 is not reduced to the value 3. Instead, we create a “promise” that when the value of the expression isOdd (1 + 2) is needed, we'll be able to compute it. The record that we use to track an unevaluated expression is referred to as a thunk. This is all that happens: we create a thunk, and defer the actual evaluation until it's really needed. If the result of this expression is never subsequently used, we will not compute its value at all.
Short circuiting
Many languages need to treat the logical-or operator specially so that it short circuits if its left operand evaluates to True. In Haskell, (||) is an ordinary function: non-strict evaluation builds this capability into the language.
thunk
The result of applying a function may be a thunk.
- Haskell学习笔记1
- Haskell笔记1
- haskell笔记(1)
- haskell学习笔记(1)
- haskell笔记
- 【笔记】Haskell
- haskell 笔记
- Haskell语言学习笔记(1)
- Haskell 学习笔记 1 --环境搭建与类型系统(Haskell Tutorial 1--Getting start with Haskell)
- haskell(1)
- Haskell 学习笔记
- Haskell 错误笔记
- haskell笔记(2)
- haskell笔记(3)
- Haskell笔记(4)
- Haskell笔记(5)
- Haskell笔记(6)
- haskell 趣学指南笔记-1type and typeclass
- Java设计模式圣经连载(02)-工厂方法(Factory Method)模式
- 2012-07-13存储过程
- 使用Vitamio打造自己的Android万能播放器(1)——准备
- MFC显示jpg图片
- linux 电源管理
- Haskell笔记1
- 摄像机标定和立体标定
- 数据库三范式经典实例解析
- VNC连接黑屏的问题
- linux系统下安装mysql
- Linq小记
- CButton&MFC
- 关于fieldset标签
- gdb使用说明