2017-01-20 11 views
2

私は、OptionListという名前の新しいデータ型を持つファイルOptionList.hsを持っています。パターンが重複している、なぜそれが起こっているのですか?

module OptionList (
    OptionList, 
    voidOption, 
    (+:) 
) where 


data OptionList a b = EmptyOpt | OptionList { optListHead :: a, optListTail :: b } deriving (Read) 

instance (Show a, Show b) => Show (OptionList a b) where 
    show (OptionList voidOption a) = "{" ++ (show a) ++"}" 
    show (OptionList a voidOption) = "{" ++ (show a) ++"}" 
    show (OptionList a b) = "{"++ (show a) ++ ", " ++ (show b) ++"}" 
    show voidOption = "" 




voidOption::(OptionList Int Int) 
voidOption = EmptyOpt 



(+:) :: a -> b -> (OptionList a b) 
infixr 5 +: 
t1 +: t2 = OptionList t1 t2 

そして私は、メインのファイルtodo.hs

import OptionList 


main = do 
    print (0 +: "test" +: voidOption) 

を持っている。しかし、コンパイラはOptionList.hsでパターンマッチングが重なっていることを語っている:私はOptionListが示されたされたときにEmptyOptを非表示にします:

OptionList.hs:12:9: Warning: 
    Pattern match(es) are overlapped 
    In an equation for ‘show’: 
     show (OptionList a voidOption) = ... 
     show (OptionList a b) = ... 

私が実行すると、実際には重なっています。これは、次の出力を生成します。

しかし、なぜこれらのパターンが重なっている

{{}} 

(私はそれが{0, {"test"}}になりたかったですか)? aであるようなラインで

答えて

8

show (OptionList voidOption a) = "{" ++ (show a) ++"}" 

voidOptionは、新鮮なローカル変数です。下に定義されている変数voidOptionとの関係はありません。基本的に、上記の行は、

show (OptionList b a) = "{" ++ (show a) ++"}" 

と等価であり、したがって常に次の行と一致して重複します。

パターンのすべての変数をパターンで定義された変数と見なすと、これを覚えやすいです。ある意味では、それらは "in"ではなく "out"になる値です。警告(-Wall)をオンに

voidOption影世界のいずれかの結合新しいローカル以来、この間違いについて警告すべきです。

パターンでは、代わりにEmptyOptコンストラクタを使用する必要があります。例えば。

show (OptionList EmptyOpt a) = "{" ++ (show a) ++"}" 
+0

ありがとうございます!提案通りにコードを更新しましたが、より多くのエラーが発生しました。私の編集 –

+0

@BrunoCorrêaZimmermannを参照してください。新しいコードに関する新しい問題のため、新しい質問として "更新"が良いでしょう。しかし、小さなヒント:あなたの 'show'実装では、' a'と 'b'の2つの型があります。あなたが知っていることは、' show'nできることです。なぜあなたは 'OptionList'型のコンストラクタとパターンマッチングできると思いますか? – amalloy

+2

ごめんなさい。私は新しい質問をします –

関連する問題