2013-10-24 19 views
1

這是參考先前的問題。大小順序字母百分比函數

String letter percentages in Haskell

因爲什麼是返回的時刻是在按字母順序排列,而我希望它的大小順序,字母開頭的比例最高和下降?

+1

您是否嘗試過[sortby](http://hackage.haskell.org/package/base-4.6.0.1/docs/Data-List.html#v:sortBy)。編寫一個接收元組並返回一個Ordering的函數,就完成了。 – DiegoNolan

+0

sortBy做什麼?它與排序有何不同? – Eddie

+0

單擊鏈接,閱讀類型 – DiegoNolan

回答

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,因爲它們是,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剛剛取代sortOrd約束與定義Ord例如,compare的確切功能。事實上,這正是如何sort實現

sort = sortBy compare 

我們可以通過編寫代碼相當於Ord實例上的元組剛剛比較第二元素寫sortEm(我們Float小號!)。


那麼我們該怎麼做呢?那麼,我們可以使用Ord實例爲Float

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 

但是,這也一個很常見的成語,結合compareon,因此,即使有一個特別的名字。在Data.Ord我們

comparing f = compare `on` f 

因此,我們實際上是非常經濟的,而寫sortEm

sortEm = comparing snd 

而這可能是有人真正寫這段代碼的方式。

letterFrqs = sortBy (comparing snd) . frqLetters 

它現在就像英文的讀法。