2

この質問は、antal sz が回答したこのFunction Composition VS Function Applicationに関連しています。

どうやってこれを手に入れることができますか?

map has type (a -> b) -> [a] -> [b]
head has type [a] -> a
map head  has type [[a]] -> [a]

次のコードに関数合成の型エラーがあるのはなぜですか?

 test :: [Char] -> Bool
 test xs = not . null xs

 getMiddleInitials :: [String] -> [Char]
 getMiddleInitials middleNames = map head . filter (\mn -> not . null mn) middleNames

しかし、これには型エラーはありません

getFirstElements :: [[a]] -> [a]
getFirstElements = map head . filter (not . null)

関数合成を利用するには、ポイントフリー関数を書く必要がありますか? 関数合成の使い方がまだよくわかりません。

助けてください。ありがとう。

4

2 に答える 2

4

それは、関数適用x yが合成よりも優先されるためです。x . y

 test :: [Char] -> Bool
 test xs = (not . null) xs
 -- #      ^          ^

 getMiddleInitials :: [String] -> [Char]
 getMiddleInitials middleNames = (map head . filter (\mn -> (not . null) mn)) middleNames
 -- #                            ^                          ^          ^    ^
于 2010-06-26T10:09:28.400 に答える
3

ここでのエラーは、実際には非常に単純です。最後の質問に対する私の回答の最後の部分を覚えていれば、演算子は関数適用以外の.よりも優先されます。したがって、あなたの例を考えてみましょう

test :: [Char] -> Bool
test xs = not . null xs

これは として解析されtest xs = not . (null xs)ます。もちろん、null xstypeBoolがあり、ブール値を構成できないため、型エラーが発生します。したがって、例を次のように機能させることができます。

test :: [Char] -> Bool
test xs = (not . null) xs

getMiddleInitials :: [String] -> [Char]
getMiddleInitials middleNames =
  (map head . filter (\mn -> (not . null) mn)) middleNames

もちろん、このように書くのは珍しいことですが、問題なく動作します。

いいえ、ポイントフリースタイル以外にも関数合成の用途があります。1 つの例は、いくつかのもの ( orの引数mapなどfilter) に関数合成を使用し、残りを指定することです。たとえば、次の不自然な例を見てみましょう。

rejectMapping :: (a -> Bool) -> (a -> b) -> [a] -> [b]
rejectMapping p f = map f . filter (not . p)

これは部分的に無意味です (not . pたとえば、 と、最後の引数を省略しました) が、部分的に無意味です ( と の存在p) f

于 2010-06-26T10:14:55.067 に答える