2

xorHaskellでパターンマッチングを使用して定義しようとしています:

(xor) :: Bool -> Bool -> Bool
True    xor False   = True
False   xor True    = True
True    xor True    = False
False   xor False   = False

ただし、これによりエラーが発生します。

Invalid type signature: (xor) :: Bool -> Bool -> Bool
Should be of form <variable> :: <type>

このエラーがスローされる理由について私は混乱しています。xorまた、スクリプトなどに置き換えると&&正常に読み込まれます。

4

2 に答える 2

15

型シグネチャの場合は、演算子のみを括弧で囲む必要があります。

(&&) :: Bool -> Bool -> Bool

通常の関数は、なしで記述されるものとします。

xor :: Bool -> Bool -> Bool

方程式を定義する際には、それをバッククォートで囲む必要があります。

True `xor` True = False

中置記法を使用して定義する場合。バックティックなしで、プレフィックス表記を使用して定義できます。

xor True False = True

ただし、注意してください

  • xorBitsクラスの関数であるため、に使用するBoolと予期しない場合があります
  • xor ≡ (/=)
于 2013-02-12T16:27:36.293 に答える
9

Haskellは識別子演算子記号を区別します。識別子は英数字とプラス'であり、それ自体が有効な用語です。したがって、識別子prefixに関数型がある場合は、として呼び出すことができますprefix arg1 arg2。演算子名は一連の記号であり、と呼ばれarg1 !&$ arg2ます。1 ただし、識別子を中置演算子として使用したり、中置演算子を識別子として扱いたい場合があります。したがって、プレフィックス関数名を`sで囲むと、それは演算子になり、中置として使用できます(必須)arg1 `prefixFunc` arg2。逆に、中置演算子名を括弧で囲むと、構文的に有効になるため、接頭辞形式で呼び出すことができます(!&$) arg1 arg22

変数の型シグネチャを宣言するときは、変数の名前を識別子として指定する必要があります。3の ような通常の関数名の場合xor、それは単なる名前です。のような演算子の場合&&、前述のように括弧で囲みます。これが、を記述する理由です(&&) :: Bool -> Bool -> Bool。したがって、あなたは書くだろう

xor :: Bool -> Bool -> Bool
True  `xor` False = True
False `xor` True  = True
True  `xor` True  = False
False `xor` False = False

2つの変更を加える必要があることに注意してください。定義行のバッククォートを省略した場合は、パターンマッチングを実行しようとしているようになります。Trueこれは、2つの引数をとるコンストラクターのように見えxor、最初の引数になります。4

(また、キックのためだけに、より短い定義: xor = (/=):-))


Haskell 2010レポートの引用:

1字句構造は§2.4にあります

2式の構造は§3.2にあります。

3型シグネチャの構造は§4.4.1にあり、§3.2のvarの定義を参照しています。

4バインディングの構造は§4.4.3にあります。

于 2013-02-12T16:49:20.587 に答える