関数アプリケーションから関数構成へのHaskellタイプエラー
-
30-09-2019 - |
質問
この質問はこれに関連しています 関数構成vs関数アプリケーション Antal SZによって答えられました。
どうすればこれを手に入れることができますか?
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)
関数構成を利用するために、ポイントフリー関数を書く必要がありますか?私はまだ関数構成の使用をあまり理解していません。
助けてください。ありがとう。
解決
ここでのエラーは実際には本当に簡単です。の最後の部分を覚えている場合 あなたの最後の質問に対する私の答え, 、 .
オペレーターは何よりも優先されます それ外 関数アプリケーション用。したがって、あなたの例を考えてください
test :: [Char] -> Bool
test xs = not . null xs
これは解析されます test xs = not . (null xs)
. 。もちろん、 null xs
タイプがあります Bool
, 、そしてブール値を作成することができないため、タイプエラーが発生します。したがって、あなたはあなたの例をそうするように機能することができます:
test :: [Char] -> Bool
test xs = (not . null) xs
getMiddleInitials :: [String] -> [Char]
getMiddleInitials middleNames =
(map head . filter (\mn -> (not . null) mn)) middleNames
もちろん、このように書くことは珍しいことですが、うまくいきます。
いいえ、ポイントフリースタイル以外には、機能構成の他の用途があります。 1つの例は、いくつかのものに関数構成を使用することです(例えば への議論 map
また filter
)、しかし残りを指定します。たとえば、この不自然な例を考えてみましょう。
rejectMapping :: (a -> Bool) -> (a -> b) -> [a] -> [b]
rejectMapping p f = map f . filter (not . p)
これは部分的にポイントフリーです(not . p
, 、たとえば、最終的な議論を中断しました)が、部分的にはポイントフルです(の存在 p
と f
).
他のヒント
それは、関数アプリケーションのからです 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
-- # ^ ^ ^ ^
所属していません StackOverflow