更新时间: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:
第一个参数必须是谓词函数,即一个函数,当它的参数为您要查找的值时返回True,否则返回False
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.fromJust
从Maybe
中提取元组,如下所示:
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.