複数のパターンマッチングでは、ポイントフリーであっても、異なる数の引数は不可能です!
foo True b = b + 2
foo _ = id
たとえば、機能しません。しかし
foo True = (+2)
foo _ = id
します。機能の一部でのみポイントフリーを使用できる場合もあるので...
なんで?GHCには難しすぎる?:'(
なんで?GHCには難しすぎる?
いいえ。GHCにとってはそれほど難しいことではありません。実際、これは Haskell Report の誤りです。
参照: Haskell Report 2010 > Declarations and Bindings > Function bindings
関数バインディングは、変数を関数値にバインドします。変数 x の関数バインディングの一般的な形式は次のとおりです。
x p1 1 … p1 k match1
…<br> x pn 1 … pn k matchn[...何とか何とか...]
翻訳: 関数の一般的なバインド形式は、式と意味的に同等です(つまり、単純なパターン バインド)。
x = \ x 1 … x k -> ケース (x 1 , …, x k ) の
(p11, …, p1k) match1
…<br> (pn1, …, pnk) matchn
x iは新しい識別子です。
(私のものを強調)
関数定義はラムダ & ケース式と意味的に同等ですが、Mihai が提案するように、必ずしもそのようにコンパイルされるとは限りません。
問題は、Haskell のレポートでは、式の左側に同じ数の入力が必要になるように関数宣言を定義しているということです。これは、1 番目と n 番目の関数宣言行 (および暗黙的に、その間のすべての行) の両方で同じままであるという事実によって明らかにされています。これが制限の理由です。GHC の実装の詳細とは関係ありません。k
tl;dr
それを許可しないという選択は、スタイルの問題です。– オーガスト
各関数方程式には、同じ数の引数が必要です。これが、最初の例が失敗する理由です。
それを修正するには、使用します
foo True b = b + 2
foo _ x = id x
ご覧のとおり、両方の方程式の引数の数は同じです。
パターン マッチングを含む複数の方程式は、case 式に変換されます。あなたの場合foo
、大まかに次のように翻訳されます
foo a b = case a of
True -> b + 2
_ -> id x
の両方の (すべての) ブランチはcase
同じタイプでなければならないため、最初の例は次のように変換されます。
foo a b = case a of
True -> b + 2
_ -> id
ブランチの種類が異なるため、間違っています。
もちろん、これは手を振っています。舞台裏で実際に起こっていることはもっと複雑です。