Haskell:在元组列表中查找函数

时间:2015-12-14 23:32:10

标签: list haskell find tuples

我想知道是否有人可以帮助我。假设我有一个(String,Int)类型的元组,以及一个这样的元组[("Strength",12),("Stamina",60),("Health",100)]的列表。如果我实际上不知道列表中的元组是什么顺序但是只包含某个元组,那么如何使用函数find来提取元组Int的{​​{1}}值字符串("Stamina",60)是否存在?

我试过

"Stamina"

其中value = snd ( find ("Stamina", _ ) stats ) 是元组列表,stats定义为

value

..但它不起作用:/所以任何想法?

4 个答案:

答案 0 :(得分:7)

您似乎正在尝试将模式用作find的参数。不幸的是,这不会起作用。您只能在几个地方进行模式匹配,例如警卫和case表达式。

正如Jubobs在评论中所说,在这种情况下使用Data.List.lookup是理想的,但使用Data.List.find也是可能的。

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

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

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

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

  2. 该函数返回Maybe a,这意味着它可能会返回Nothing,您必须处理此问题。

  3. 创建谓词函数非常简单。你只需要使用==运算符测试元组的第一个值,也许是lambda函数,例如:

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

    现在你可以这样打电话给find

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

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

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

    稍后使用matchFirst函数作为find的参数:

    find (matchFirst "Stamina") stats
    

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

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

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

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

    最后,最后一件事:您已经说value的类型为a -> Int,即一个接受任何内容并返回Int的函数。事实并非如此。相反,它只是一个单一的价值。

答案 1 :(得分:0)

更多替代品,不一定比上述更好:

使用模式作为OP建议

find (\c -> case c of ("A", _) -> True ; _ -> False) [("B",4), ("A", 5), ("C", 7)]

同样,利用扩展

{-# LANGUAGE LambdaCase #-}
find (\case ("A", _) -> True ; _ -> False) [("b",4), ("A", 5), ("C", 7)]

答案 2 :(得分:0)

使用fst和等级==的简单单行。

您需要导入Data.ListData.Maybe

> let set stats = [("Strength",12),("Stamina",60),("Health",100)]
> snd $ fromJust $ find ((=="Strength") . fst) stats
12

答案 3 :(得分:0)

fn :: Eq a => a -> [(a, b)] -> b
fn x = snd . fromJust . find ((== x) . fst)

然后你会

tuples :: [(String, Int)]
tuples = undefined  -- a list of tuples

string :: String
string = "Stamina"

value :: Int
value = fn string tuples