2012-04-07 7 views
1

いくつかのタイプRecordあり範囲は

getAssignment :: (Year, Month, Day) -> [Record] -> [Record] 
getAssignment (year, month, day) = filter matchDate 
    where matchDate (BirthdayRecord _ (Birthday month day)) = True 
     matchDate (DatingRecord (DatingDate year month day) _) = True 
     matchDate _ = False 

getAssignmentのこの定義は、エラーのため正しくありません。

warning: Defined but not used: `year' 

実際に、それは、私のためにその01驚きの一種でありますパターン一致部分のgetAssignmentyearのパターン一致部分のは、matchDateと一致しません。

したがって、yearのスコープ境界はどこで開始され、終了しましたか? whereセクションのために起こりますか?

Btwこのエラーは、(year, month, day)個の変数を使用していくつか重複して使用すると回避できます。

getAssignment' :: (Year, Month, Day) -> [Record] -> [Record] 
getAssignment' date = filter (matchDate date) 
    where matchDate (_, m, d) (BirthdayRecord _ (Birthday month day)) = 
      month == m && day == d 
     matchDate (y, m, d) (DatingRecord (DatingDate year month day) _) = 
      year == y && month == m && day == d 
     matchDate _ _ = False 

どのように書き換えられますか?

答えて

4

スコープは、パターン全体の中の変数が常に新しい変数バインディングを定義することを除いて、式全体(where節の定義を含む)です。

同じ名前を再使用する代わりに、内部バインディングで異なる変数名を使用する必要があります。それは外側のスコープから変数を隠蔽するように変数名を再利用

getAssignment :: (Year, Month, Day) -> [Record] -> [Record] 
getAssignment (year, month, day) = filter matchDate 
    where matchDate (BirthdayRecord _ (Birthday month' day')) 
      = month == month' && day == day' 
     matchDate (DatingRecord (DatingDate year' month' day') _) 
      = year == year' && month == month' && day == day' 
     matchDate _ = False 

はシャドウと呼ばれています。 -Wall(またはこの警告のみを有効にする場合は-fwarn-name-shadowing)を使用すると、GHCは警告を発する必要があります。

編集:あなたの特定の機能のためにが、これはおそらくそれを書くための明確な方法である:

getAssignment :: (Year, Month, Day) -> [Record] -> [Record] 
getAssignment (year, month, day) = filter matchDate 
    where matchDate (BirthdayRecord _ birthday) = birthday == Birthday month day 
     matchDate (DatingRecord date _)  = date == DatingDate year month day 
     matchDate _       = False 

しかし、あなたがそれを使用したい場合は、パターンの一部に名前を与えることを避けることができませんたとえそれを他のものと比較するだけであっても。

+0

'month'と' month''変数を抑制する方法はありますか? –

+0

申し訳ありませんが、私はあなたのコメントを理解していません。あなたが求めていることの詳細を教えてください。 – dave4420

+0

'f x = x == y'の定義を見たとき、' x'変数を冗長に使用しているため 'f y == True'のように書き直したいと思います。その場合、 'year''、' month''と 'day''変数を取り除くために同じトリックを使いたいと思います。 –

0

パターンマッチングの形式は次のとおりです。コンストラクタバインディング1バインディング2 ...ここで、バインディングは使用量の一部に名前を付けることを許可しています(右側のみです)。それは、左辺の値を数学的に計算するときに行うことができるすべてです。 最初の例では、バインディングにバインドされた名前を付けることで一致を制約するように思われますが、それはそのようには動作しません。あなたが望むものはガードを見てください。