【问题标题】:Haskell : using the `find` function on a list of tuplesHaskell:在元组列表上使用`find`函数
【发布时间】:2015-12-14 23:32:10
【问题描述】:

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

如果我实际上不知道元组在列表中的顺序,但只知道包含字符串 @ 的某个元组,我如何使用函数 find 来提取元组 ("Stamina",60)Int 值987654327@存在吗?

我试过了

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

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

  value :: a -> Int    

..但它不起作用:/所以有什么想法吗?我专门打算使用find

【问题讨论】:

  • 查找...lookup.
  • 这是一个我专门使用 find 的练习

标签: list haskell find tuples


【解决方案1】:

您似乎正在尝试将模式用作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,你必须处理这个问题。

创建谓词函数非常简单。您只需要使用== 运算符来测试元组的第一个值,也许是一个像这样的 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 的函数。实际上并非如此。相反,它只是一个值。

【讨论】:

    【解决方案2】:

    更多的选择,不一定比上面的好:

    按照 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)]
    

    【讨论】:

      【解决方案3】:

      这里使用fst 和相等== 的简单单行。

      您需要导入Data.ListData.Maybe

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

      【讨论】:

        【解决方案4】:
        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 
        

        【讨论】:

          猜你喜欢
          • 2019-09-08
          • 1970-01-01
          • 2013-03-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-01-05
          • 2013-11-14
          相关资源
          最近更新 更多