0

这是参考之前的问题。

Haskell中的字符串字母百分比

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

4

1 回答 1

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?好吧,我们可以sortFloat原样使用 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约束。确实,这就是实现的方式OrdOrdcomparesort

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

但是,这也是一个很常见的成语,结合compareand on,所以即使它也有一个特殊的名字。在Data.Ord我们有

comparing f = compare `on` f

所以我们在写作的时候实际上可以很省钱sortEm

sortEm = comparing snd

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

letterFrqs = sortBy (comparing snd) . frqLetters

现在读起来有点像英语。

于 2013-10-24T22:03:17.047 回答