我想知道是否有人可以帮助我.假设我有一个类型的元组(String,Int)
,以及这样的元组列表[("Strength",12),("Stamina",60),("Health",100)]
.如果我实际上不知道元组在列表中的顺序是什么,但只是包含字符串的某个元组存在,我如何使用该函数find
来提取Int
元组的值?("Stamina",60)
"Stamina"
我试过了
value = snd ( find ("Stamina", _ ) stats )
stats
元组列表在哪里,value
定义为
value :: a -> Int
..但它不起作用:/所以任何想法?
看起来你正在尝试使用模式作为参数find
.不幸的是,这不会奏效.您只能在一些地方进行模式匹配,例如警卫和case
表情.
正如Jubobs在评论中所说,Data.List.lookup
在这种情况下使用它是理想的,但使用Data.List.find
肯定也是可能的.
如果你看看它的类型Data.List.find
,你会发现它看起来像这样:
find :: Foldable t => (a -> Bool) -> t a -> Maybe a
这告诉你两件重要的事情:
第一个参数必须是一个谓词函数,即当它的参数是你要查找的值时返回True的函数,否则返回False
该函数返回a Maybe a
,这意味着它可能会返回Nothing
,您必须处理此问题.
创建谓词函数非常简单.你只需要使用==
运算符来测试元组的第一个值,也许是lambda函数,例如:
\(x, _) -> x == "Stamina"
现在你可以find
像这样打电话:
find (\(x, _) -> x == "Stamina") stats
或者,您可以创建一个通用函数,用于将元组的第一个元素与已知值进行比较,如下所示:
matchFirst x (y, _) = x == y
然后使用matchFirst
函数作为参数find
:
find (matchFirst "Stamina") stats
现在让我们来看看我的第二点:你如何处理find
没有找到任何东西?
如果您完全确定它将永远成功,您可以简单地使用Data.Maybe.fromJust
从以下内容中提取元组Maybe
:
value = snd $ fromJust $ find (matchFirst "Stamina") stats
否则,如果查找实际上可能失败,那么您可以执行许多操作.例如,您可以使用合理的默认值,Data.Maybe.fromMaybe
或者您可以更改您value
的类型Maybe Int
.
最后,最后一件事:你已经说过value
有类型a -> Int
,即一个接受任何东西并返回的函数Int
.事实并非如此.相反,它只是一个单一的价值.