• 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]
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这里有新东西!
    [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 作为参数(用于对列表进行排序)。 如果你想简单地按升序排列事物,你可以使用 (<) 作为这个参数。

  • 相关阅读:
    北邮《计算机网络》网络层笔记
    来聊一聊std::function和lambda性能效率问题
    2022-08-19 mysql/stonedb聚合aggregate多线程并行化-概要设计
    前端npm打包及报错解决
    左神高阶进阶班4 (尼姆博弈问题、k伪进制、递归到动态规划、优先级结合的递归套路、子串的递归套路,子序列的递归套路,动态规划的压缩技巧)
    web前端高频面试题:如何保证Redis缓存与数据库的同步?
    ListableBeanFactory学习
    Web前端—小兔鲜儿电商网站底部设计及网站中间过渡部分设计
    react的组件
    【LeetCode】210. 课程表 II——拓扑排序
  • 原文地址:https://blog.csdn.net/kirsten111111/article/details/126326119