2012-10-05 5 views
23

HaskellNetライブラリーからの例:いない場合Haskellのレコードアクセサがアンダースコアで始まる場合、通常何を意味しますか?

data MailboxInfo = MboxInfo { _mailbox :: MailboxName 
          , _exists :: Integer 
          , _recent :: Integer 
          , _flags :: [Flag] 
          , _permanentFlags :: [Flag] 
          , _isWritable :: Bool 
          , _isFlagWritable :: Bool 
          , _uidNext :: UID 
          , _uidValidity :: UID 
          } 
       deriving (Show, Eq) 

は、少なくともHaskellの慣例に従って、コンパイラに、フィールド名にアンダースコアが何かを意味するのでしょうか?

答えて

21

、例えばfst (x, _) = xのアンダースコア接頭辞(レコードフィールドまたはその他)は、識別子をコードを読んだ人が無視するか、ある種のユーザ対話のためにコンパイラによって無視されるべきであることを示すために使用されます。理由。

下線、「_」、小文字として扱われ、どこ小文字発生する可能性があります。これは単なる慣習ではなく、明示的に述べin the Haskell Report何かに基づいていることを

注意手紙缶。しかし、 "_"はすべてそれ自身が予約済みの識別子であり、パターンではワイルドカードとして使用されます。未使用の識別子に警告を出すコンパイラは、アンダースコアで始まる識別子の警告を抑制することが推奨されます。これにより、プログラマーは未使用と予想されるパラメーターに "_foo"を使用することができます。

一つの例は、私は推測するだろうどの(レコードフィールドに基づいてレンズを生成する一般的な例のように、アンダースコアせずに同等の識別子を定義するテンプレートHaskellの、で使用するために意図されている定義は何をされるだろう、あなたの例はやっている)。この場合、識別子は実際の定義よりもTHに多く入力されます。 THによって生成されたコードは、アンダースコアの前に付いた識別子を実際に使用しても使用しなくてもよい。

ただし、アンダースコアのプレフィックスは、通常の小文字の識別子とは何も変わりません。

+3

によって解決された:http://www.haskell.org/ghc/docs/7.4.1/html/ users_guide/options-sanity.html – jberryman

+0

とにかく使用されている「未使用」の識別子についての警告も参照してください:https://ghc.haskell.org/trac/ghc/ticket/4959 – Lemming

1

これは単なるプログラミングの実践例です。

Haskellのレコードフィールドラベルは実際にはトップレベルの名前付き関数なので、モジュールの名前空間を汚染します。フィールドラベルにアンダースコアを追加すると、同じ名前の別の関数を自由に定義することができます。

+2

実際にはその非常に機能を使用します。この場合、アンダースコアは珍しいでしょう。これはしばしば新しいタイプのケースである。 'newtype Reader e a = Reader {runReader :: e - > a}' –

1

最近私はあなたの質問に関連するものを発見しました。

すべての値が有効であることを証明するために、自分のタイプのインスタンスが構築される場所を制御したかったのです。だから私は、独自のモジュールでそれを宣言した:

module Coords (Coords(), -- hide the constructor 
       x,y,buildCoords) where 

data Coords = Coords { x :: Int, y :: Int } 

buildCoords :: Int -> Int -> Coords 
buildCoords x y | x < 0 || y < 0 = error "omg" 
buildCoords x y = Coords { x = x, y = y } 

その後、私はこのモジュールの外に、何のコードが無効COORDSを作成することができなかったから、推論しました。

私は間違っていました。 xyは公開されているため、無効なCoords値を取得するにはlet c = buildCoords 1 1 in c { x = -1 }を使用するだけです。

しかし、この構文は、xとyが型のレコードセレクタであるためにのみ可能です。有効な値のみを許可する方法は次のとおりです。

module Coords (Coords(), -- hide the constructor 
       x,y,buildCoords) where 

data Coords = Coords { _x :: Int, _y :: Int } 
x = _x 
y = _y 

buildCoords :: Int -> Int -> Coords 
buildCoords x y | x < 0 || y < 0 = error "omg" 
buildCoords x y = Coords { _x = x, _y = y } 

ここで、xとyは単なる正規の関数です。 c { x = -1 }構文はコンパイルされず、他のモジュールはレコードセレクタ_xにアクセスできません。

問題はあなたがGHCの扱いは、アンダースコア、接頭辞方法識別子と警告をここで見ることができますアンダースコア;-)

+0

しかし、レコードセレクタが未使用であると思わないためには、 'x_'や' y_'などを使ってください。 – Lemming

関連する問題