2012-02-20 15 views
21

三元論理テーブルを作成し、<=>と呼ぶ演算子のために私自身の関数を作りたいと思います。Haskellで演算子を作成するにはどうすればよいですか?

たとえば、私はこれをしたいと思いますが、それは正しくありません。これを行う正しい方法は何ですか?

data Ternary = T | F | M 
deriving (Eq, Show, Ord) 

<=> :: Ternary -> Ternary -> Ternary 
<=> T F = F 
<=> T T = T 
<=> T M = M 
<=> F F = T 
<=> F T = F 
<=> F M = M 
<=> M F = M 
<=> M T = M 
<=> M M = T 
+3

ちょうどnとして'M <=> M 'は' T'ではなく 'M'でなければなりません。しかし、それはあなたの "たぶん"の意味にかかっています。 – bitmask

+0

'infixl'、' infixr'を使ってアリティとアソシアティビティを設定できることを忘れないでください... – Landei

答えて

36

ちょうどあなたのオペレータの周りに括弧を追加します。

(<=>) :: Ternary -> Ternary -> Ternary 
(<=>) T F = F 
(<=>) T T = T 
(<=>) T M = M 
(<=>) F F = T 
(<=>) F T = F 
(<=>) F M = M 
(<=>) M F = M 
(<=>) M T = M 
(<=>) M M = T 

これは、中置フォームからプレフィックスフォームになります。また、あなただけの定義で中置を使用することができます。

-- Works: 
(<^>) :: Int -> Int -> Int 
a <^> b = a + b 

-- Doesn't work: 
{- 
<^> :: Int -> Int -> Int 
<^> a b = a + b 
-} 

-- Works: 
letters :: Int -> Int -> Int 
letters a b = a + b 

-- Doesn't work: 
{- 
(letters) :: Int -> Int -> Int 
a letters b = a + b 
-} 

私も、約束 - Haskellは複雑なルールを学ぶ価値がある:シンボルと

(<=>) :: Ternary -> Ternary -> Ternary 
T <=> F = F 
T <=> T = T 
T <=> M = M 
F <=> F = T 
F <=> T = F 
F <=> M = M 
M <=> F = M 
M <=> T = M 
M <=> M = T 
+0

':' cons演算子のようなものを作る方法はありますか? ':' cons演算子は、この特別な機能を持っていて、右側のすべてをリストとみなします。私は ':'演算子を再作成しようとしていましたが、常に右側に括弧が必要です。 – CMCDragonkai

+0

@ClarkGaebel:おそらく '中置詞 'に言及するのも面白いかもしれませんか? –

+0

@CMCDragonkai次のように同じことをすることができます: 'data List a = Nil | a: - そして、重要な部分: 'infixr 5:'をリストします。 5である必要はありませんが、これはリストの優先順位であり、 'infixr'でなければならず、' infixl'や 'infix'でなければなりません。 'infixl 9'がデフォルトの – semicolon

8

関数名がないものとは異なる構文を持っています。

+11

です。完全性のために:' 'a'''b''は動作します... –

1

次のようにあなたが(行単位)の定義を簡略化することができます。

(<=>) :: Ternary -> Ternary -> Ternary 
T <=> T = T 
F <=> F = T 
M <=> M = T 
M <=> _ = M 
_ <=> M = M 
_ <=> _ = F 
+0

それは私にとっては単純には見えません。 –

+0

それで、私はそこに '(行に沿った)'を持っています。しかし、クラリティは議論の余地がある。私はコードをより良く見ることができます。なぜなら、生の表形式の定義を見るのとは対照的に、実際に何をするのかを推測する必要があるからです。しかし、それは私です。 –

+0

IMOそれは簡単です、私はすぐに見ることができますが、それらが等しい場合はtrueを返しますが、それらが1つは多分、次に戻って多分、それらが等しくない場合は、 。私が驚くべきことが分かる部分は 'M <=> M'が 'T '部分であることだけです。 – semicolon

0

をあなたはEqOrdを持っているので、次の操作を行うことができます。

data Ternary = T | F | M 
deriving (Eq, Show, Ord) 

(<=>) :: Ternary -> Ternary -> Ternary 
x <=> y = if x == y then T else max x y 

あなたが変更に起こるならばそのようにM <=> M == M、次に行うことができます:

data Ternary = M | T | F 
deriving (Eq, Show, Ord, Enum) 

(<=>) :: Ternary -> Ternary -> Ternary 
x <=> y = fromEnum $ rem (toEnum x * toEnum y) 3 
関連する問題