Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 在元组列表中查找最大元素_Haskell - Fatal编程技术网

Haskell 在元组列表中查找最大元素

Haskell 在元组列表中查找最大元素,haskell,Haskell,我是Haskell的初学者。我有一个在Haskell中使用的元组列表:结构如下[(a,b),(c,d),(e,f),(g,h)] 我想要的是根据第二个值返回此元组中的最大元素: 因此,如果元组列表是[(4,8)、(9,10)、(15,16)、(10,4)],我希望最大元素是(15,16) 但我不知道怎么做。这是我迄今为止的尝试 maximum' :: (Ord a) => (Num a) => [(a,b)] -> a maximum' [] = error "maxim

我是Haskell的初学者。我有一个在Haskell中使用的元组列表:结构如下
[(a,b),(c,d),(e,f),(g,h)]

我想要的是根据第二个值返回此元组中的最大元素: 因此,如果元组列表是
[(4,8)、(9,10)、(15,16)、(10,4)]
,我希望最大元素是
(15,16)

但我不知道怎么做。这是我迄今为止的尝试

maximum' ::  (Ord a) => (Num a) => [(a,b)] -> a  
maximum' [] = error "maximum of empty list"  
maximum' [(x,y)] = -1
maximum' (x:xs)   
  | snd x > snd(xs !! maxTail) = 0
  | otherwise = maxTail  
  where maxTail = maximum' xs + 1
我得到了这个错误信息,这对我来说毫无意义:

newjo.hs:23:25:
Could not deduce (a ~ Int)
from the context (Ord a, Num a)
  bound by the type signature for
             maximum' :: (Ord a, Num a) => [(a, b)] -> a
  at newjo.hs:19:14-47
  `a' is a rigid type variable bound by
      the type signature for maximum' :: (Ord a, Num a) => [(a, b)] -> a
      at newjo.hs:19:14
In the second argument of `(!!)', namely `maxTail'
In the first argument of `snd', namely `(xs !! maxTail)'
In the second argument of `(>)', namely `snd (xs !! maxTail)'`

我需要一些关于如何做到这一点的帮助。

惯用的方法是使用
maximumBy(比较snd)


a~Int
消息意味着出于某种原因,Haskell推断
a
必须是
Int
,但类型签名并不将其限制为
Int
s。GHC告诉您它的源位置,这是因为您将它用作
的第二个参数
,这是一种
Int

使用库的惯用方法是使用

然后剩下的就是定义类型为
a->a->
的函数,以便它知道如何对元素排序。构造
排序
对象的常用方法是使用

compare :: (Ord a) => a -> a -> Ordering

到目前为止,提供的解决方案非常优雅,您可能应该在编写的任何实际代码中使用它们。但这里有一个版本,它使用了与您使用的相同的模式匹配样式

maximum' :: Ord a => [(t, a)] -> (t, a)
maximum' []     = error "maximum of empty list"
maximum' (x:xs) = maxTail x xs
  where maxTail currentMax [] = currentMax
        maxTail (m, n) (p:ps)
          | n < (snd p) = maxTail p ps
          | otherwise   = maxTail (m, n) ps
maximum':Ord a=>[(t,a)]->(t,a)
最大值“[]=错误“空列表的最大值”
最大值’(x:xs)=最大尾x xs
其中maxTail currentMax[]=currentMax
maxTail(m,n)(p:ps)
|n<(snd p)=最大尾p ps
|否则=最大尾(m,n)ps

该解决方案避免了在索引上做手脚,而是只跟踪当前最大元素,当遍历整个列表时返回该元素。避免使用列表索引通常被认为是良好的做法。

还值得注意的是,Haskell中的元组是。因此,可以对它们进行排序和比较。它们使用字典排序(主要按元组的第一个元素排序,次要按第二个元素排序等),因此以下情况适用:

maximum [(1,1),(1,8),(2,1),(2,6)] == (2,6)
如果你想得到第二个元素最大的元组。您可以将tuple的元素交换为maximum函数,然后交换结果元素,如下所示:

maximum' :: (Ord a, Ord b) => [(a,b)] -> (a,b)
maximum' l = swap $ maximum $ map swap l
             where swap (x, y) = (y, x) 

尽管要使其工作,两个元组元素都必须是的实例。

实际上,错误是因为'xs!!maxTail',其中maxTail::a但是!!取整数,-1适用于任何Numa@Amos当前位置我猜我读得太快了,猜错了。谢谢您的更正。也许您应该提到您必须导入
数据。Ord
才能使用
比较
。谢谢。我最喜欢这一个,但所有其他解决方案也都很有用。您不需要定义
swap
,它已经存在于Haskell中:
maximum' :: (Ord a, Ord b) => [(a,b)] -> (a,b)
maximum' l = swap $ maximum $ map swap l
             where swap (x, y) = (y, x)