大小订单字母百分比功能

时间:2013-10-24 19:20:30

标签: string haskell tuples

这是参考先前的问题。

String letter percentages in Haskell

因为目前返回的内容按字母顺序排列,而我希望按大小顺序排列,从最高百分比的字母开始下降?

1 个答案:

答案 0 :(得分:1)

你想要一个像

这样的功能
letterFrqs :: String -> [(Char, Float)]

letterFrqs "PLATYPUS" == [('A',36),('P',18),('L',9),('S',9),('T',9),('U',9),('Y',9)]

给出一个

frqLetters :: String -> [(Char, Float)]

frqLetters "PLATYPUS" == [('A',36),('L',9),('P',18),('S',9),('T',9),('U',9),('Y',9)]

所以你需要的是

letterFrqs = sortEm . frqLetters

sortEm :: [(Char, Float)] -> [(Char, Float)]

我们如何撰写sortEm?好吧,我们sort可以Floatsort :: [Float] -> [Float]。我们想把这种排序提升到我们的元组中。

通常,Haskell函数有时可能具有类似名称的堂兄弟。在这种情况下,sort :: Ord a => [a] -> [a]有一个名为sortBy :: (a -> a -> Ordering) -> [a] -> [a]的堂兄。这里的区别在于Ord实例是“内联的”。更具体地说,这是Ord

instance Eq a => Ord a where
  compare :: a -> a -> Ordering

因此,我们注意到sortBy仅使用定义sort实例Ord的确切函数替换Ord的{​​{1}}约束。实际上,这正是compare的实施方式

sort

我们可以通过在元组上编写与sort = sortBy compare 实例等效的代码来编写sortEm,这些实例仅比较第二个元素(我们的Ord s!)。


那我们该怎么做?好吧,我们可以将Float实例用于Ord

Float

现在,聪明地看待Haskell的人可能会注意到我们也可以这样写compareOurTuples (char1, percent1) (char2, percent2) = compare percent1 percent2 sortEm = sortBy compareOurTuples

compareOurTuples

这是一种常见的习语,有点像预先编写一个“两次”的功能。它被称为compareOurTuples tup1 tup2 = compare (snd tup1) (snd tup2) ,它位于on

Data.Function

但是,是一个非常常见的习惯用法,它结合了compareOurTuples = compare `on` snd compare,所以即使它有一个特殊的名字。在on我们有

Data.Ord

因此,在撰写comparing f = compare `on` f 时,我们实际上非常经济。

sortEm

这可能是某人实际编写此代码的方式。

sortEm = comparing snd

现在有点像英语。