4

私は Haskell の初心者で、ポイントフリー関数で遊んでいます。私は2つの関数に問題があります.ラムダボットのソリューションは完全に判読できず、コードが難読化されていたため、関数を簡素化する方法がある場合に備えてここで質問しています.

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

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

この関数のポイントフリー バージョンをfoldrandで作成しようとしまし>>=たが、成功しませんでした。

2 番目の関数は、リストを元の要素を含むタプルのリストにマップし、それらがリスト内でどのくらいの頻度で発生したかを示します。

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

どこでcount a = length.filter(==a)。読みやすさを維持しながら、この関数のポイントフリー バージョンを作成できるかどうかはわかりませんが、確認したいと思います。

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

4

1 に答える 1

17

さて、func1折り畳みとして書くことができます: func1 = foldr (\x xs -> x : filter (/= x) xs) []. 1ただし、標準関数と同じであるため、その必要はありませんnub

また、 から2コンビネータfunc2を使用していくつかのポイントを削除できます。(&&&) :: (a -> b) -> (a -> c) -> a -> (b,c)Control.Arrow

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

その後、完全にポイントフリーにすることができます:

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

しかし、率直に言って、最後のステップを実行するにはラムダボットを使用する必要がありました。その機能を元の形に保つことをお勧めします。ポイントフリー スタイルは、理解を助ける場合にのみ役立ちます。関数をポイントフリーにするのが難しい場合は、おそらく逆効果です。

1これは完全にポイントフリーにすることができますfoldr (liftM2 (.) (:) (filter . (/=))) [](lambdabot に感謝します!) が、これもお勧めしません。すべての状況に対応できるポイントフリーのコンビネーターはありません。

2 (&&&)には、実際にはより一般的なタイプがあります。Arrowだけでなく、任意の で動作します(->)。しかし、それはここでは関係ありません。

于 2012-04-14T22:08:53.827 に答える