简体   繁体   English

尝试根据Haskell编写函数,并根据-Wall,我需要一个与(_:_:_)匹配的模式_该模式是什么意思,为什么我需要它?

[英]Trying to write a function in Haskell and according to -Wall I need a pattern that matches (_:_:_) _ What does this pattern mean and why do I need it?

So I wanted to try to make this function myself (multiples everything in a list by 3 and returns a new list): 因此,我想尝试自己制作此功能(将列表中的所有内容乘以3,然后返回一个新列表):

list = [1,2,3,4,5,6,7,8,9,10]
list2 = [3 * x | x <- list]

And I managed to get this using guards (basically it stops when x reaches the bound of the list): 而且我设法使用了防护(基本上在x到达列表的边界时停止了):

tripleMultList :: [Int] -> Int -> [Int]
tripleMultList lst x
   | null lst = []
   | length lst - 1 == x = (lst !! x * 3) : []
   | otherwise = (lst !! x * 3) : tripleMultList lst (x + 1)

Then I decided to try to do it with pattern matching: 然后,我决定尝试通过模式匹配来做到这一点:

tripleMultList :: [Int] -> Int -> [Int]
tripleMultList [] x = []
tripleMultList [y] x | x == (length [y] - 1) = [y] !! x : []
tripleMultList [y] x = [y] !! x : tripleMultList [y] (x + 1)

But whenever I'd try to run this function I would get a non exhaustive pattern matching error so I checked ghci -Wall and it said that I needed a pattern matched to 但是每当我尝试运行此功能时,我都会得到一个非详尽的模式匹配错误,因此我检查了ghci -Wall并说我需要一个与

(_:_:_) _ 

which I assume would take the form of 我认为它将采取以下形式

tripleMultList (_:_:_) _ = something

I'm aware that 我知道

(_:_:_)

has to do with selecting elements from a list and separating them from the list itself, though I have no idea why this would apply to my function. 与从列表中选择元素并将其与列表本身分开有关,尽管我不知道为什么这会应用于我的函数。 I also don't know what "_" means or does and how it applies to my function either. 我也不知道“ _”的含义或作用以及它如何应用于我的函数。

So I guess my question is, what does this pattern mean and why do I need it when I have roughly the same thing in the version of my function which uses a guard and that one works fine? 所以我想我的问题是,这种模式的含义是什么,当我在使用防护的函数版本中具有大致相同的东西并且可以正常工作时,为什么需要它?

Your function takes two arguments. 您的函数有两个参数。 GHCI is telling you that you haven't provided a definition for a function call that follows the pattern GHCI告诉您尚未提供遵循该模式的函数调用的定义

tripleMultList (_:_:_) _

ie when the first argument matches the pattern _:_:_ and the second argument matches the pattern _ . 也就是说,当第一个参数匹配模式_:_:_ ,第二个参数匹配模式_ The pattern _ matches everything. 模式_匹配所有内容。 The pattern _:_:_ matches lists where the first element is anything, the second element is anything, and the rest of the list is anything. 模式_:_:_匹配列表,其中第一个元素是任何东西,第二个元素是任何东西,列表的其余部分是任何东西。 In other words, _:_:_ matches lists of at least two elements. 换句话说, _:_:_匹配至少两个元素的列表。

Look at the cases you defined: 查看您定义的情况:

tripleMultList [] x = []
tripleMultList [y] x | x == (length [y] - 1) = [y] !! x : []
tripleMultList [y] x = [y] !! x : tripleMultList [y] (x + 1)

That's: 那是:

  • First argument: empty list; 第一个参数:空列表; second argument: anything. 第二个论点:什么。
  • First argument: list with a single element; 第一个参数:带有单个元素的列表; second argument: anything; 第二个论点:任何东西; only if x == (length [y] - 1) is true. 仅当x == (length [y] - 1)为true时。
  • First argument: list with a single element; 第一个参数:带有单个元素的列表; second argument: anything; 第二个论点:任何东西; only if the condition above is not met. 仅在不满足上述条件的情况下。

This leaves out the case when the first argument is a list with at least two elements. 当第一个参数是一个至少包含两个元素的列表时,就省去了这种情况。

If you want to follow the decomposition in your first definition, then you need to use y in the second and third definitions instead of [y] . 如果要遵循第一个定义中的分解,则需要在第二个和第三个定义中使用y而不是[y] The pattern y (a variable) matches anything (of the right type) and gives it the name y . 模式y (一个变量)匹配任何(正确类型的)东西,并为其命名为y The pattern [y] matches any list of one element and gives this element the name y . 模式[y]匹配一个元素的任何列表,并将该元素命名为y

You almost never want to use !! 您几乎永远都不想使用!! , especially not for iterating over a list. ,尤其是不适用于遍历列表。 Remember the definition of a list: 记住列表的定义:

 data [] a = [] | a : [] a

There are only two patterns you need to match: the empty list ( [] ) and the non-empty list ( x:y ). 您只需要匹配两种模式:空列表( [] )和非空列表( x:y )。 You have the empty-list case correct: multiplying every element of an empty list yields another empty list. 您的空列表大小写正确:将一个空列表的每个元素相乘会产生另一个空列表。

tripleMultList [] = []

For a non-empty list, you need something only slightly more complicated. 对于非空列表,您只需要稍微复杂一点即可。 You have the first element x and the rest of the elements as y . 您拥有第一个元素x ,其余元素为y All you need to do is multiply x by 3, and add it to the list produced by multiplying everything in y by 3: 您所需要做的就是将x乘以3,并将其添加到将y的所有乘以3产生的列表中:

tripleMultList (x:y) = let x' = 3 * x
                           y' = tripleMultList y
                       in x' : y'

Note that we can generalize this for any operation on x : 请注意,我们可以对x上的任何操作进行概括:

doSomething :: (a -> b) -> [a] -> [b]
doSomething _ [] = []
doSomething f (x:y) = let x' = f x
                          y' = doSomething f y
                      in x' : y'

tripleMultList = doSomething (\x -> 3 * x)

This type of operation is so common that doSomething is already defined in Haskell, but it is called map instead. 这种操作非常普遍,以至于Haskell中已经定义了doSomething ,但是它被称为map

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何比较两个列表并返回差值? (python中的差异函数不会返回我需要的东西) - How do you compare 2 lists and return the difference? (difference function in python does not return what I need) 为什么Haskell不允许在理解中进行模式匹配? - Why does Haskell not allow pattern matching in comprehensions? 为什么在Python路径中需要4个反斜杠? - Why do I need 4 backslashes in a Python path? 为什么 PriorityQueue 需要 Comparable? - Why do I need Comparable for PriorityQueue? 为什么我需要display:block - why do I need the display:block 我需要在 Haskell 中返回字符串而不是 True - I need to return the string instead of True in Haskell 得墨忒耳定律 - 为什么我需要使用吸气剂? - Law of Demeter - why do I need to use a getter? 为什么我需要第二个带有 append 的 for 循环来制作此列表? - Why do I need a second for loop w/ append to make this list? 为什么在Java中使用thenComparing时需要进行类型转换 - Why do I need to typecast when using thenComparing in Java 为什么我们需要在使用 map 函数时将 list 写在前面,因为 split() 已经返回了一个列表? - Why do we need to write list at front while using map function as split() already returns a list?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM