Haskell:在元组列表上使用"find"功能 [英] Haskell : using the `find` function on a list of tuples

查看:214
本文介绍了Haskell:在元组列表上使用"find"功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道是否有人可以帮助我.假设我有一个(String,Int)类型的元组,以及这样的元组[("Strength",12),("Stamina",60),("Health",100)]的列表.

I was wondering if anyone could help me. Suppose I have a tuple of type (String,Int), and a list of such tuples [("Strength",12),("Stamina",60),("Health",100)] .

如果我实际上不知道元组在列表中的顺序,而只是某个包含字符串的特定元组<,则如何使用函数find提取元组Int的值("Stamina",60) c5>存在吗?

How can I use the function find to extract the Int value of the tuple ("Stamina",60) if I don't actually know what order the tuples are inside the list but only that a certain tuple containing the string "Stamina" exists?

我尝试过

value =   snd ( find ("Stamina", _ ) stats )

其中stats是元组列表,而value定义为

where stats is the list of tuples and value is defined as

  value :: a -> Int    

..但是它不起作用:/那么有什么主意吗?我专门打算使用find.

..but it doesn't work :/ So any ideas? I'm specifically meant to use find.

推荐答案

似乎您正在尝试使用模式作为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.

这篇关于Haskell:在元组列表上使用"find"功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆