Common interface for several modules

I want to give the user the ability to run the program from import DryRunfirst, and then using import Doif he thinks that everything is correct.
So, there is a module that does the actual work:

doThis ∷ SomeStack ()
doThis = actuallyDoThis
...
doThat ∷ SomeStack ()
doThat = actuallyDoThat

and a module for a shy user:

doThis ∷ SomeStack ()
doThis = liftIO $ putStrLn "DoThis"
...
doThat ∷ SomeStack ()
doThat = liftIO $ puStrlLn "DoThat"

The problem is that I cannot be sure that the interfaces in Doand are the DryRunsame (the compiler cannot help), and this mess is difficult to maintain during development.
Are there common idioms to solve this problem?

+3
source share
1 answer

You can confirm the modules in question. That is, in the base module, determine the data type:

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 , . , Base Client, , MyModule. .

doNothing = MyModule (return ()) (return ())
addTracing impl = MyModule ((liftIO $ putStrLn "DoThis") >> doThis_ impl) 
                           ((liftIO $ putStrLn "DoThat") >> doThat_ impl)

DryRun addTracing doNothing, .

+2

All Articles