1. 变量与常量
Haskell 中的变量一旦定义即不可变,因此变量更像常量。定义变量使用 =
赋值。
name = "Alice"
age = 30
注意事项:Haskell 是懒惰求值的,变量的值在需要时才会被计算。
2. 数据类型
Haskell 是强类型语言,常用的数据类型有 Int
、Float
、Char
和 Bool
。
height :: Float
height = 1.75
isStudent :: Bool
isStudent = True
易错点:确保变量类型与值类型一致,Haskell 编译器会检查类型一致性。
3. 条件表达式
Haskell 中的条件表达式使用 if
和 then
、else
关键字。
status = if age > 18 then "Adult" else "Minor"
注意事项: if
表达式必须有 else
分支。
4. 函数
使用 let
或 where
关键字定义局部函数。
greet :: String -> String
greet name = "Hello, " ++ name
注意事项:Haskell 函数是纯函数,不会改变外部状态。
5. 递归
递归是 Haskell 处理循环的一种方式。
factorial :: Int -> Int
factorial 0 = 1
factorial n = n * factorial (n - 1)
易错点:确保递归有基准情况,否则会导致无限递归。
6. 数据结构
Haskell 支持列表、元组等数据结构,列表用 []
定义。
names = ["Alice", "Bob", "Charlie"]
pair = (1, "one")
注意事项:列表元素必须是相同类型,元组可以包含不同类型。
7. 类型类
Haskell 中的类型类类似接口,Eq
和 Show
是常见的类型类。
data Person = Person { name :: String, age :: Int } deriving (Show, Eq)
注意事项: deriving
关键字自动实现常用类型类。
8. 模式匹配
模式匹配是 Haskell 中非常有用的功能,用于检查和解构数据结构。
describe :: Int -> String
describe 1 = "One"
describe 2 = "Two"
describe _ = "Other"
易错点:使用 _
作为通配符匹配所有其他情况,避免遗漏。
9. 惰性求值
Haskell 默认是惰性求值,表达式仅在需要时计算。
infiniteList = [1..] -- 无限列表
注意事项:使用惰性求值时需谨慎,避免无穷计算。
10. Monad
Monad 是 Haskell 中的一种抽象概念,常用于处理输入输出和错误。
greet :: IO ()
greet = do
putStrLn "Enter your name:"
name <- getLine
putStrLn ("Hello, " ++ name)
注意事项:IO 操作需在 Monad 中使用,避免副作用。
高级与小众用法
列表解析
Haskell 支持列表解析语法,生成新的列表。
squares = [x^2 | x <- [1..10]]
注意事项:确保列表生成条件合理,以避免性能问题。
高阶函数
Haskell 支持将函数作为参数传递或返回。
applyTwice :: (a -> a) -> a -> a
applyTwice f x = f (f x)
易错点:高阶函数的类型签名应明确参数和返回值类型。
部分应用
Haskell 支持函数的部分应用,通过传入部分参数生成新函数。
addThree :: Int -> Int -> Int -> Int
addThree x y z = x + y + z
addTwo = addThree 5 3 -- 部分应用
注意事项:部分应用适合简化多参数函数,但参数过多时应考虑代码可读性。
自定义类型和别名
使用 type
为已有类型创建别名,data
定义新类型。
type Age = Int
data Person = Person String Age
易错点:避免类型名称与函数名重复。
函数组合
Haskell 使用 .
运算符进行函数组合。
compose :: (b -> c) -> (a -> b) -> a -> c
compose f g x = f (g x)
注意事项:组合时确保函数的参数和返回值类型匹配。
Guard 表达式
Guard 表达式类似于条件判断,用于选择不同的分支。
factorial :: Int -> Int
factorial n
| n <= 1 = 1
| otherwise = n * factorial (n - 1)
注意事项:使用 |
定义多个条件分支,otherwise
表示默认分支。