12

System.Random.StdGenを調べて、このコードをソースで確認しました。

data StdGen = StdGen Int32 Int32

モジュールはStdGenもエクスポートしているようです。

module System.Random (

    RandomGen(next, split, genRange)

    , StdGen

    ...

ただし、コードでこれを実行できないのはなぜですか。

Prelude System.Random> StdGen 1 2

Not in scope: data constructor `System.Random.StdGen'**

一方、私はこれを行うことができます、

module F (Foo) where

    import GHC.Int

    data Foo = Foo GHC.Int.Int32 GHC.Int.Int32 deriving (Show)

Prelude> Foo 1 2

Foo 1 2

このデータコンストラクタが実際にどのように隠されているか教えていただけませんか?

4

2 に答える 2

22

ここで理解すべきことが 2 つあります。エクスポート構文と、コンパイルされた値と解釈された値の間の GHCi の動作の違い。

構文のエクスポート

この構文を使用してモジュールからエクスポートする

module System.Random (
    -- ...
    , StdGen
    -- ...

コンストラクターではなく、データ型のみをエクスポートするようGHCに指示します(両方が同じ名前であっても)。エクスポートする場合は、次のように、コンストラクターをデータ型名の後の括弧内に明示的にリストできます。

    StdGen(StdGen)

または、次のようにすべてのコンストラクターを使用してデータ型をエクスポートできます。

    StdGen(..)

GHCi の動作

さらに、GHCi は、解釈されたモジュールをロードするとき、エクスポート リストによって非表示になっている場合でも、常にモジュールのトップレベルで表示可能なすべてのエンティティを表示できます。Fooこれは、開発とデバッグを容易にするためであり、あなたが表示される理由です。

「すべて」が表示されるこのモードは*、GHCi プロンプトでモジュール名の前に a を付けることで反映されます。がある場合*はすべてが表示され、そうでない場合はエクスポートされたエンティティが表示されます。

コマンドを使用して:mスコープからモジュールを追加または削除する場合、モジュールを -form で追加するかどうかを選択できます*

しかしコンパイルされたモジュール (およびSystem.Random通常のようなライブラリ モジュールがコンパイルされている) の場合、*-form は使用できないため、これらのモジュールでは常にエクスポート リストが尊重される状況になります。

GHCi のスコープ動作の完全な説明については、ドキュメントを参照してください。

于 2013-03-07T14:53:48.690 に答える
8

ソースを見ると、次の行に沿って何かが表示されます。

module System.Random
    (
    -- stuff...
    , StdGen
    -- even more stuff...
    )

この構文は、コンストラクターではなく、のみがエクスポートされることを意味します。コンストラクターもエクスポートする場合は、次のようにします。

module System.Random
    ( StdGen(..)
    -- ...
    )
于 2013-03-07T14:41:06.787 に答える