問題のモジュールを確認できます。
module Base where
data MyModule = MyModule {
doThis_ :: SomeStack(),
doThat_ :: SomeStack()
}
あなたは(アンダースコアがすぐに明らかになるであろう理由)をエクスポートするために、各モジュールを必要とするもので:それは、ベースモジュールにデータ型を定義し、あります。
例えば、このタイプの値を定義するとあなたは、各モジュールにできます
module DryRun(moduleImpl) where
import Base
moduleImpl :: MyModule
moduleImpl = MyModule doThis doThat
-- doThis and doThat defined as above, with liftIO . putStrLn
module Do(moduleImpl) where
import Base
moduleImpl :: MyModule
moduleImpl = MyModule doThis doThat
-- doThis and doThat defined as above, where the real work gets done
私は確信してMyModule
変更する場合は、型チェッカーがすることを確認するために、レコードの構文を使用してMyModule
値を構築しません。ほとんどの場合、不平を言い始めます。クライアントモジュールで
あなたは今、あなたは同じ操作は両方のモジュールによってエクスポートされていることを知っている
module Client where
import DryRun
-- import Do -- uncomment as needed
doThis = doThis_ moduleImpl
doThat = doThat_ moduleImpl
-- do whatever you want here
を行うことができます。これは退屈で厄介ですが、Haskellにはファーストクラスのモジュールがないので、モジュールシステムの限界を常に克服する必要があります。良いことは、ベースモジュールとクライアントモジュールを一度書かなければならず、MyModule
値で動作するコンビネータの定義を開始できることです。例えば。
doNothing = MyModule (return()) (return())
addTracing impl = MyModule ((liftIO $ putStrLn "DoThis") >> doThis_ impl)
((liftIO $ putStrLn "DoThat") >> doThat_ impl)
は、私が間違っていない場合は、addTracing doNothing
によってDryRun
モジュールの実装を置き換えることができます。
同じtypeclassの2つの実装インスタンスにオプションを設定していますか? –
@GregBaconまあ、モナドスタックの2つのコピーは確かにオプションですが、コピーが含まれていない何かがあればそれを使用します。 –
両方のモジュールでhaddockを実行し、結果のドキュメントを比較しますか? –