gpt4 book ai didi

haskell - 使用模式查找第 n 个元素

转载 作者:行者123 更新时间:2023-12-04 13:28:13 25 4
gpt4 key购买 nike

我正在通过 Learn You A Haskell 来学习 Haskell 的基础知识。我对函数式编程和模式匹配都非常满意,但后者更喜欢 Mathematica 是如何做到的。

本着与 head 的幼稚实现相同的精神在第 4.1 章中,我进行了 last 的简单实现。作为:

last1 :: [a] -> a
last1 (_:x:[]) = x

但是,调用 last1 [1,2,3,4]报错 Exception: ... Non-exhaustive patterns in function last1 .我知道这个错误意味着指定的模式不涵盖所有可能的输入,通常需要一个包罗万象的模式(我没有提供)。但是,我不确定为什么我的输入会出现此错误。

问题一:我的理解(我的错误方法)是第一个元素被 _ 捕获。其余的分配给 x ,这不是我想要的。但是,这不应该给出类型错误吗,因为我指定了 [a] -> a , 但是 x现在是一个列表?

请注意,这不是关于如何编写有效的 last函数——我知道我可以把它写成(以及其他可能性)
last2 :: [a] -> a
last2 [x] = x
last2 (_:x) = last2 x

问题二:沿着更好地理解 Haskell 中的模式匹配的相同主题,我如何使用模式匹配来挑选最后一个元素或更一般地, n给定列表中的第一个元素,例如 [1..10] ?

This answer建议您可以使用与 ViewPatterns 的模式匹配来绑定(bind)最后一个元素。扩展名,但似乎很奇怪,没有像 head 这样的类似“简单”模式

在 Mathematica 中,我可能会将其写为:
Range[10] /. {Repeated[_, {5}], x_, ___} :> x
(* 6 *)

挑选出第 6 个元素和
Range[10] /. {___, x_} :> x
(* 10 *)

挑选出非空列表的最后一个元素。

如果本文稍后会涉及到这一点,我深表歉意,但我试图将遇到的每个主题和概念与我知道的其他语言的处理方式联系起来,以便我能够理解差异和相似之处。

最佳答案

要理解第一次尝试的结果,您需要了解
列表数据被定义。列表有一种特殊的语法,但你会
像这样写。

data List a = (:) a (List a)
| []

因此,您的列表 [1 .. 10] 实际上的结构为
(1 : (2 : (3 : (4 : []))))

此外,由于 (:) 运算符的右结合性,您的模式
对于 last1 实际上看起来像
last1 :: [a] -> a
last1 (_:(x:[])) = x

这就是为什么 'x' 与列表中的元素具有相同类型的原因;这是第一个
(:) 构造函数的参数。

模式匹配允许您解构列表等数据结构,但您
需要知道他们必须这样做的“形状”。这就是为什么你不能直接
指定将提取列表的最后一个元素的模式,因为有
是列表可以具有的无限长度。这就是为什么工作
solution (last2) 使用递归来解决问题。你知道什么模式
一个具有长度的列表以及在哪里可以找到最终元素;为一切
否则,您可以丢弃第一个元素并提取最后一个元素
生成的更短的列表。

如果您愿意,您可以添加更多模式,但这并不能证明
有帮助。你可以把它写成
last2 :: [a] -> a
last2 (x:[]) = x
last2 (_:x:[]) = x
last2 (_:_:x:[]) = x
...
last2 (x:xs) = last2 xs

但是如果没有无限数量的案例,您将永远无法完成功能
对于所有长度的输入列表。当您考虑到以下事实时,它甚至更加可疑
列表实际上可以无限长;你会用什么模式来匹配它?

关于haskell - 使用模式查找第 n 个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12648255/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com