【问题标题】:Writing a function from definitions?根据定义编写函数?
【发布时间】:2015-10-23 00:17:20
【问题描述】:

首先,我想让你们都知道我对 Haskell 还很陌生,所以为了增加知识等,我一直在尝试问题,但我很困惑。我想我快到了,但如果能提供一些更有经验的建议,我们将不胜感激。问题来了:

运动队由其名称和他们在上一场比赛中得分的数量表示,例如("Newcastle",[3,3,3,0])。该数据由类型定义建模:

type TName = String
type Points = [Int]
type Team = (TName,Points)

据此,我必须定义以下函数,如果他们的积分总和更大,则将一个团队的排序高于另一团队:

sortPoints :: [Team] -> [Team]

这是我尝试过的:

sortPoints :: [Team] -> [Team]
sortPoints [_,()] -> []
sortPoints [_,(x:xs)] = sum[x|x<-xs]

一旦我到达这里,我不太确定如何添加条件来检查积分总和,任何指针将不胜感激,因为我仍在接受许多 Haskell 功能。

【问题讨论】:

  • 查看hoogle 并搜索:sortBycompareonsnd - 您可以将它们拼在一起以获得您想要的东西(一起拼图我真的在谈论作曲
  • @Carsten:这可能是一个答案。 :D
  • @Zeta yours 有更多信息;) (+1)
  • @Carsten:不过,这已经成为一种习惯:你 post a comment,我根据该评论写了一个社区 wiki 答案:D。

标签: function haskell types definition


【解决方案1】:

注意:这篇文章是用 literate Haskell 写的。您可以将其保存为Team.lhs 并尝试一下。话虽如此,这基本上是卡斯滕评论的更长版本。如果您仍然试图解决问题,请使用 hoogle 并查找功能,尽管如果您首先仅使用 sortBy 管理事情也可以。


首先,我们要处理列表,所以您要导入 Data.List

> module Team where
> import Data.List

它包含一个名为sortBy的函数:

sortBy :: (a -> a -> Ordering) -> [a] -> [a]

sortBy 的第一个参数应该是一个比较列表中两个元素并返回的函数

  • LT 如果第一个小于第二个,
  • EQ 如果两者相等,
  • GT 如果第一个大于第二个。

所以我们需要一些东西,它需要两个团队并返回他们的订单:

> -- Repeating your types for completeness
> type TName  = String
> type Points = [Int]
> type Team   = (TName, Points)
>
> compareTeams :: Team -> Team -> Ordering

现在,您想根据他们的积分总和来比较团队。你不需要他们的名字,所以你可以只捕获这对的第二部分:

> compareTeams (_, s1) (_, s2) =

我们需要积分的总和,因此我们将sum1sum2 定义为各个团队的总和:

>       let sum1 = sum s1
>           sum2 = sum s2

现在我们可以比较这些总和:

        in if sum1 < sum2 
             then LT
             else if sum1 == sum2 
                     then EQ
                     else GT

但是,这相当冗长,并且已经有一个类型为 Ord a =&gt; a -&gt; a -&gt; Ordering 的函数。它被称为comparePrelude 的一部分:

>       in sum1 `compare` sum2

这样更简洁。现在我们可以轻松定义sortTeams

> sortTeams :: [Team] -> [Team]
> sortTeams = sortBy compareTeams

就是这样,我们完成了!


好吧,我撒谎了,我们还没有 100% 完成。模块Data.Ord 包含一个名为comparing 的函数,非常方便:

comparing :: Ord b => (a -> b) -> a -> a -> Ordering
comparing f x y = f x `compare` f y -- or similar

sndsum 一起,您可以在一行中定义sortTeams

sortTeams = sortBy (comparing $ sum . snd)

Carsten 提到的替代 onon 来自 Data.Function

sortTeams = sortBy (compare `on` sum . snd)

【讨论】:

  • 应该有更多像这样的 Literate Haskell 答案:)
猜你喜欢
  • 2016-03-18
  • 1970-01-01
  • 2022-06-15
  • 1970-01-01
  • 2023-03-27
  • 2022-08-19
  • 2023-02-05
  • 1970-01-01
  • 2019-03-14
相关资源
最近更新 更多