这是参考之前的问题。
因为目前返回的内容是按字母顺序排列的,而我希望它按大小顺序排列,从百分比最高的字母开始向下?
你想要一个像
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
按Float
原样使用 s sort :: [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
's约束。确实,这就是实现的方式Ord
Ord
compare
sort
sort = sortBy compare
我们可以sortEm
通过编写与元组上的实例等效的代码来编写,该Ord
实例仅比较第二个元素(我们Float
的 s!)。
那么我们该怎么做呢?好吧,我们可以将Ord
实例用于Float
.
compareOurTuples (char1, percent1) (char2, percent2) = compare percent1 percent2
sortEm = sortBy compareOurTuples
现在,对 Haskell 有敏锐眼光的人可能会注意到我们也可以compareOurTuples
这样写
compareOurTuples tup1 tup2 = compare (snd tup1) (snd tup2)
这是一个常见的习惯用法,有点像预先组合一个函数“两次”。它被调用on
并且它在Data.Function
.
compareOurTuples = compare `on` snd
但是,这也是一个很常见的成语,结合compare
and on
,所以即使它也有一个特殊的名字。在Data.Ord
我们有
comparing f = compare `on` f
所以我们在写作的时候实际上可以很省钱sortEm
。
sortEm = comparing snd
这可能是某人实际编写此代码的方式。
letterFrqs = sortBy (comparing snd) . frqLetters
现在读起来有点像英语。