2012-04-14 11 views
4

私はハスケルの初心者です。私はポイントフリーの関数で遊んでいます。私は2つの機能に問題があります。lambdabotのソリューションは完全に読めなくなり、コードが難読化されてしまったので、機能を単純化する方法がある場合はここで尋ねています。ハスケル関数をポイントフリーにする

最初の機能は、リストから重複を削除します。

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

私はfoldr>>=で、この関数のポイント・無料版を作ってみましたが、成功しませんでした。

第2の関数は、リストを元の要素を含むタプルのリストとリスト内で発生した頻度にマップします。

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

ここで、count a = length.filter(==a)である。私は可読性を維持しながらこの関数の無点バージョンを作ることさえ可能であるかどうかはわかりませんが、私は確信しています。

2つの機能をポイントフリーにするための助けがあれば幸いです。

答えて

17

まあ、func1は、フォールド:func1 = foldr (\x xs -> x : filter (/= x) xs) []と書くことができます。 ただし、標準機能nubと同じであるため、これを行う必要はありません。

そして、あなたはControl.Arrowから(&&&) :: (a -> b) -> (a -> c) -> a -> (b,c) コンビネータを使用してfunc2からいくつかのポイントを削除することができます。その後、完全にポイントの無行うことができ

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

:率直に言って、

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

しかし、ラムダボットを使ってその最後のステップを踏んでいなければなりませんでした。その機能を元の形に保つことをお勧めします。ポイントフリーのスタイルは、理解を助けるときにのみ役立ちます。関数をポイントフリーにするのが難しい場合は、おそらく非生産的です。

foldr (liftM2 (.) (:) (filter . (/=))) [](ありがとう、もう一度、lambdabot!)として完全にポイントフリーにすることができますが、やはり私は本当にこれをお勧めしません。 の場合、ポイントフリーのコンビネータはありません。毎回の状況になります。

は実際にはより一般的なタイプです。 ではなく、Arrowで動作します。しかし、ここでは関係ありません。

関連する問題