从定义中编写函数?

1 haskell types function definition

首先,我想让大家都知道我对Haskell很新,所以为了增加知识等,我一直在尝试问题,而且我很困惑.我想我差不多了,但一些更有经验的建议将不胜感激.这是问题:

一个体育团队的名字和他们在上一场比赛中得分的数量就像这样("Newcastle",[3,3,3,0]).此数据由类型定义建模:

type TName = String
type Points = [Int]
type Team = (TName,Points)
Run Code Online (Sandbox Code Playgroud)

从这里我必须定义以下函数,如果他们的积分总和更大,则命令一个团队高于另一个团队:

sortPoints :: [Team] -> [Team]
Run Code Online (Sandbox Code Playgroud)

这就是我尝试过的:

sortPoints :: [Team] -> [Team]
sortPoints [_,()] -> []
sortPoints [_,(x:xs)] = sum[x|x<-xs]
Run Code Online (Sandbox Code Playgroud)

一旦我到达这里,我不太确定如何添加检查点总和的条件,任何指针都会非常感激,因为我仍然会接受很多Haskell功能.

Zet*_*eta 7

注意:这篇文章是用文字Haskell编写的.你可以保存它Team.lhs并尝试它.话虽如此,它基本上是Carsten评论的更长版本.如果您仍然试图解决问题,请使用hoogle并查找功能,但如果您sortBy只是先处理事情就行了.


首先,我们将开始处理列表,因此您需要导入Data.List.

> module Team where
> import Data.List
Run Code Online (Sandbox Code Playgroud)

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

sortBy :: (a -> a -> Ordering) -> [a] -> [a]
Run Code Online (Sandbox Code Playgroud)

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

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

因此,我们需要一些需要两个团队并返回其排序的东西:

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

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

> compareTeams (_, s1) (_, s2) =
Run Code Online (Sandbox Code Playgroud)

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

>       let sum1 = sum s1
>           sum2 = sum s2
Run Code Online (Sandbox Code Playgroud)

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

        in if sum1 < sum2 
             then LT
             else if sum1 == sum2 
                     then EQ
                     else GT
Run Code Online (Sandbox Code Playgroud)

然而,这相当冗长,并且已经存在具有类型的函数Ord a => a -> a -> Ordering.它被称为compare和部分Prelude:

>       in sum1 `compare` sum2
Run Code Online (Sandbox Code Playgroud)

这更加简洁.现在我们可以sortTeams轻松定义:

> sortTeams :: [Team] -> [Team]
> sortTeams = sortBy compareTeams
Run Code Online (Sandbox Code Playgroud)

就是这样,我们完成了!


好吧,我撒谎,我们不是百分之百完成的.该模块Data.Ord包含一个comparing相当方便的函数:

comparing :: Ord b => (a -> b) -> a -> a -> Ordering
comparing f x y = f x `compare` f y -- or similar
Run Code Online (Sandbox Code Playgroud)

与您一起定义snd,sum您可以sortTeams在一行中定义:

sortTeams = sortBy (comparing $ sum . snd)
Run Code Online (Sandbox Code Playgroud)

onCarsten提到的替代方案on来自Data.Function:

sortTeams = sortBy (compare `on` sum . snd)
Run Code Online (Sandbox Code Playgroud)