且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Haskell:在元组列表上使用"find"功能

更新时间:2023-02-18 13:08:27

似乎您正在尝试使用模式作为find的参数.不幸的是,那是行不通的.您只能在几个地方进行模式匹配,例如后卫和case表达式.

It seems like you're trying to use a pattern as an argument to find. Unfortunately, that won't work. You can only do pattern matching in a few places, such as guards and case expressions.

正如Jubobs在他的评论中所说,在这种情况下使用Data.List.lookup是理想的选择,但是使用Data.List.find绝对也是可行的.

As Jubobs has said in his comment, it's ideal to use Data.List.lookup in this case, but using Data.List.find is definitely possible as well.

如果查看Data.List.find的类型,您会发现它看起来像这样:

If you take a look at the type of Data.List.find, you'll see that it looks like this:

find :: Foldable t => (a -> Bool) -> t a -> Maybe a 

这告诉您两个重要的事情:

This tells you two important things:

  1. 第一个参数必须是谓词函数,即一个函数,当它的参数为您要查找的值时返回True,否则返回False

  1. The first argument has to be a predicate function, i.e. a function that returns True when it's argument is of the value you are looking for and returns False otherwise

该函数返回Maybe a,这意味着它可能会返回Nothing,您必须对此进行处理.

The function returns a Maybe a, which means it may return Nothing and you have to deal with this.

创建谓词功能非常简单.您只需要使用==运算符来测试元组的第一个值的东西,也许是像这样的lambda函数:

Creating the predicate function is pretty easy. You just need something that tests the first value of the tuple using the == operator, perhaps a lambda function such as this:

\(x, _) -> x == "Stamina"

现在您可以像这样调用find:

And now you can call find like this:

find (\(x, _) -> x == "Stamina") stats

或者,您可以创建一个通用函数来将元组的第一个元素与已知值进行比较,例如:

Alternatively, you could create a general function for comparing the first element of a tuple to a known value, such as the following:

matchFirst x (y, _) = x == y

然后将matchFirst函数用作find的参数:

And later on use the matchFirst function as an argument to find:

find (matchFirst "Stamina") stats

现在让我们看看我的第二点:您如何处理find找不到任何东西?

Now let's take a look at my second point: how do you deal with find not finding anything?

如果您完全确定它会一直成功,则可以使用Data.Maybe.fromJustMaybe中提取元组,如下所示:

If you are absolutely sure that it will always succeed, you can simply use Data.Maybe.fromJust to extract the tuple from the Maybe like this:

value = snd $ fromJust $ find (matchFirst "Stamina") stats

否则,如果查找实际上可能失败,则可以执行许多操作.例如,您可以在Data.Maybe.fromMaybe中使用合理的默认值,也可以将value更改为Maybe Int类型.

Otherwise, if the lookup can actually fail, there are many things you can do. You can, for example, use a sensible default value with Data.Maybe.fromMaybe or you can change your value to have the type Maybe Int.

最后,最后一件事:您说过value具有类型a -> Int,即,一个接受任何内容并返回Int的函数.实际上并非如此.相反,它只是一个值.

Finally, one last thing: you've said that value has the type a -> Int, i.e. a function that takes anything and returns an Int. This is not actually the case. Instead, it's just a single value.