Haskell 函数(包括条件表达式,模式匹配,在特定范围内的变化)

Haskell 函数(包括条件表达式,模式匹配,在特定范围内的变化)

常数
常量没有什么棘手的,它们只是总是返回相同值的函数
将它们视为没有参数的函数,尽管从技术上讲,您仍然可以拥有一个带参数的常量函数
freezeF = 32 – 水的冰点(华氏度)
min = 10
max = 90
zero a = 0 – 常量值 0 与输入无关
常量是严格常量; 您无法更改它们的值,因为 Haskell 中没有变量之类的东西!

功能
请记住,对于函数式编程,您需要以不同的方式考虑问题。与其说明要执行的步骤,不如考虑如何转换输入。(我知道现在这听起来很模糊,但是一旦你“得到”它,你就会“得到”函数式编程。)
编写函数最直接的方法是使用现有函数,例如
square n = n * n
odd n = n mod 2 /= 0
mod 是一个带有两个参数的函数,所以通常你会写成 mod n 2
通过在它周围加上反引号 (`),我们将它变成了一个中缀运算符(如 +、- 等),并且可以以更自然的形式使用它。
总之,mod代表得到余数

条件表达式Conditional Expressions
如果要根据输入提供不同的输出,最简单的方法是使用条件表达式,例如:
max2 a b = if a > b then a else b
注意:与许多编程语言不同,每个“if”都必须与“else”配对
您可以嵌套条件表达式,例如:
max3 a b c = if a > b then if a > c then a else c else if b > c then b else c

保护方程
受保护的方程给出了响应条件的不同方式,该等式是根据一系列警卫和结果指定的
有一个包罗万象的守卫,可用于捕获所有未明确指定的情况
以这种形式编写前面的示例:

在这里插入图片描述

模式匹配
模式匹配是另一种在函数定义中处理备选方案的方法。 例如:
mystery :: Bool -> Bool
mystery True = False
mystery False = True
这是什么功能?
另一个例子:
mystery2 :: Bool -> Bool -> Bool
mystery2 True True = True
mystery2 _ _ = False
请注意,_ 是匹配任何值的通配符模式。 Haskell 从上到下遍历模式,返回第一个匹配的值。

模式匹配在与元组和列表一起使用时特别有用
例如,库函数 fst 和 snd 定义为:
fst :: (a,b) -> a
fst (x, ) = x
snd :: (a,b) -> b
snd (
, x) = x
要理解列表中的模式匹配,我们首先需要更详细地了解列表到底是什么……

列表
我们在上一课中简要提到了列表——它们是相同类型的项目序列。
它们不是像 Bool 或 Int 这样的原始类型,而是复合或抽象数据类型。 (在语言设计的上下文中,这些术语之间存在细微的差异,目前这并不重要。)
本质上,它们一次构造一个元素,从空列表 ([]) 开始,使用 cons 运算符 ( : )。
例如,列表 [1,2,3] 等价于 1:(2:(3:[]))
两个更有用的列表运算符:
!! (xs!!n 返回 xs 的第 n 个元素,从 0 开始)
++ (xs++ys 返回 xs 的所有元素的单个列表,后跟 ys 的所有元素)
利用列表结构的这些知识,我们可以使用模式匹配。 例如,库函数 head 和 tail 可以定义为:
head :: [a] -> a
head (x:) = x
tail :: [a] -> [a]
tail (
:xs) = xs
请注意,cons 模式 (x:) 和 (:xs) 必须用括号括起来!
我们将在列表中大量使用模式匹配,特别是当我们查看递归时

Lambda 表达式
Lambda 表达式不是 Haskell 独有的(例如,您可能在 Python 中遇到过它们)。(模式匹配也用于许多其他编程语言!)
本质上,lambda 表达式是一个无名函数。 (因此在某些语言中,它们被称为“匿名函数”而不是 lambda 表达式。)
例如,将数字加倍的匿名函数可以写为
\x = 2*x
\代表希腊字母lambda

lambda
lambda 表达式的一个常见用途是与 map 函数一起使用。 例如,使用这个不使用 lambda 函数的函数:

odds :: Int -> [Int]  --返回前 n 个奇数
odds n = map f [0..n-1]
		where f x = x*2 + 1
它可以重写为:
odds n = map (\x -> x*2 + 1) [0..n-1]

这里有新东西!
[0…5] 表示生成从 0 开始的数字列表,以 1 为增量,直到我们得到一个 >= 5 的数字
[0,0.3…5] 表示生成从 0 开始的数字列表,以 0.3 为增量,直到我们得到一个 >= 5 的数字
map 是一个非常有用的库函数。 这意味着将函数应用于列表中的每个项目,返回结果列表
filter 是另一个非常有用的库函数。 这意味着将函数应用于列表中的每个项目,从原始列表中返回函数结果为 True 的项目列表

函数到运算符和运算符到函数
我们已经看到了如何将 2-argument 函数转换为中缀运算符(例如 m mod n), 我们也可以反过来:将运算符转换为 2 参数函数。
通过将运算符包含在括号中来执行此操作,例如:(+) 2 3 等价于 2 + 3
您甚至可以在括号中包含参数之一: (2+) 3 或者(+3) 2

操作员部分(Operator Sections)
一般来说,如果 ✻ 是一个运算符,则参数 x 和 y 的 (✻)、(x ✻) 和 (✻ y) 形式的表达式称为节(sections)
运算符部分具有三个主要应用:
构造紧凑的函数,例如
(1/) 是往复函数 \y -> 1/y
(/2) 是减半函数 \x -> x/2
说明运算符类型时需要,例如 对于加法运算符:
(+) :: Int -> Int -> Int
如果要将运算符用作另一个函数的参数。
例如,在 AssignmentHelp.hs 中,mergesort 将函数 cmp 作为参数(用于对列表进行排序)。 如果你想简单地按升序排列事物,你可以使用 (<) 作为这个参数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值