2011-02-06 4 views
0

イメージを表現する2つのクオッドツリーが与えられた場合、両方のクオッドツリーが同じ色で対応する位置にある場合は、値がTrueの別ブールクォードツリー「マスク」を出力し、それ以外の場合はFalseを出力する関数を作成しようとしています。発生チェック:無限型を構築できませんか?

私はこのエラーを取得しています:

Occurs check: cannot construct the infinite type: a = QT a 
    Expected type: QT (QT a) 
    Inferred type: QT a 
In the second argument of `mask', namely `c2' 
In the first argument of `Q', namely `(mask a c2)' 

をし、理由を理解することはできません。機能は次のとおりです。

data (Eq a, Show a) => QT a = C a | Q (QT a) (QT a) (QT a) (QT a) 
    deriving (Eq, Show) 

mask :: (Eq a, Show a) => QT a -> QT a -> QT Bool 
mask q1 q2 = m q1 q2 
    where 
    m (C c1) (C c2) = C (c1 == c2) 
    m (Q (C a) (C b) (C c) (C d)) (Q (C e) (C f) (C g) (C h)) 
     | and $ zipWith (==) [a, b, c, d] [e, f, g, h] = C True 
     | otherwise = Q (mask a e) (mask b f) (mask c g) (mask d f) 
    m (Q a b c d) (C c2) = Q (mask a c2) (mask b c2) (mask c c2) (mask d c2) 
    m [email protected](C _) [email protected](Q _ _ _ _) = mask q c 
    m (Q a b c d) (Q e f g h) = Q (mask a e) (mask b f) (mask c g) (mask d h) 

答えて

2

c2a型を持つが、マスクはタイプQT aの引数を望んでいます。あなたはその下の行に行うようにあなたは@パターンを使用する必要があります。

m (Q a b c d) [email protected](C _) = Q (mask a c2) (mask b c2) (mask c c2) (mask d c2) 

私は前の行にも同じ問題があると思います。

+4

これを "統一"しようとすると、コンパイラは型 "a"は "QT a"と等しくなければならないと推測します。これはQT(QT(QT ....))) QTラッパーの無限チェーンこれがこのエラーの意味です。 –

1

あなたは非常にこのラインを、これを聞いて、しかし...しませんでした:

m (Q (C a) (C b) (C c) (C d)) (Q (C e) (C f) (C g) (C h)) 

それはちょうど...

何年も前に私と友人はBASICでプログラミングを学びました。彼は非常にクールな宇宙船ゲームを作りました。私は彼にもっと多くの宇宙船を加える必要があると彼に言った、そしてそれはより冷たくなるだろう。彼はそれが難しい作業だと言った。彼は配列について知りませんでしたし、スクリーン上の8つの船のそれぞれについてコードの重複を持っていました。

くださいは次のようにクリーンなコード、何かを作る:

data SplitTree a = Leaf a | SplitNode [SplitTree a] 
    deriving (Eq, Show) 

mask :: Eq a => SplitTree a -> SplitTree a -> SplitTree Bool 
mask (Leaf x) (Leaf y) = Leaf (x == y) 
mask (SplitNode xs) (SplitNode ys) 
    | and $ zipWith (==) xs ys = Leaf False 
    | otherwise = SplitNode $ zipWith mask xs xs 

(私は、これはあなたがやろうとしていたものであることを確認してください100%ではないんだけど、私は、または意図的に導入していない場合があります宿題が好きではないので、このコードにはいくつかの単純なバグがあります)

正しいコードを書くと、正しいコードを簡単に得ることができます。それが正しくない場合は、バグを見つけやすくなります。

この混乱であなたを助けるのは難しいです。このような混乱を修正する最も簡単な方法は書き直しです。それは無駄ではないですか?

コードの小さな問題を解決する前に、それが混乱しているという大きな問題を解決してください。私と他の人たちは、維持不能なコードを維持するのに苦労しました。してください。良いコードを作りましょう。

+3

Gremoのクアッドツリーがブランチに対して4つの要素を正確に持つ場合、4つのソートを持つコンストラクタを使用する方がローズツリー(それは結局クワッドツリーと呼ばれます...)よりもはるかに優れています。リストを導入することは、効率が悪く、正確さが悪い。 –

+0

@stephen tetley:型強制木四つ木を使用することを主張すれば、固定された4つの要素を分解してリストにする2つのヘルパー関数を作ることができます。 – yairchu