2012-04-14 49 views
4

我是一名Haskell初學者,我一直在玩無點功能。我有兩個函數的問題 - lambdabot的解決方案是絕對不可讀的,並且使代碼變得混亂,所以我在這裏問,以便有方法來簡化函數。使Haskell函數免於點

第一個函數從列表中刪除重複項。

func1 :: Eq a => [a] -> [a] 
func1 [] = [] 
func1 (x:xs) = x : (func1 . filter (/=x) $ xs) 

我試圖使這一功能的免費點版本foldr>>=,但沒有成功。

第二個函數將列表映射到包含原始元素的元組列表以及它們在列表中發生的頻率。

func2 :: Eq a => [a] -> [(a, Int)] 
func2 xs = map (\f -> (f, count f xs)) xs 

其中count a = length.filter(==a)。我不確定是否可以在保持可讀性的同時製作此函數的免費版本,但我想確保。

任何幫助使這兩個功能點免費將不勝感激。

回答

17

那麼,func1可以寫成fold:func1 = foldr (\x xs -> x : filter (/= x) xs) []。 但是,您不需要,因爲它與標準功能nub完全相同。

而且你可以從func2使用(&&&) :: (a -> b) -> (a -> c) -> a -> (b,c) 組合子從Control.Arrow刪除一些要點:

func2 xs = map (id &&& (`count` xs)) xs 

,然後可以進行充分點免費電話:

func2 = (id &&&) . flip count >>= map 

但是,坦率地說,我不得不使用lambdabot來做最後一步;我建議保持原來的功能。無點式只有在幫助理解時纔有用;如果您在製作功能時遇到困難,那麼這可能會適得其反。

然後,可以完全沒有點作爲foldr (liftM2 (.) (:) (filter . (/=))) [](再次感謝,lambdabot!)但是,我真的不建議這樣做。 每個的情況沒有一個無點組合。

(&&&)實際上具有更一般的類型;它適用於任何Arrow,而不僅僅是(->)。但這在這裏沒有關係。