There'd be a standard signature somewhere, which I will call
Dist.DataFiles
, and it'd look like this
module Dist.DataFiles(getDataFileName) where
getDataFileName :: FilePath -> IO FilePath
This would have a handful of basic, built-in implementations, including the often-standard
module Dist.DataFiles.Here(getDataFileName) where
getDataFileName = return
When I create a library that uses data files, I define it as
depending on Data.DistFiles(getDataFileName)
, which is just
a signature and doesn't have a concrete implementation
module Sample.Library (getFile) where
import Dist.DataFiles (getDataFileName)
getFile :: IO String
getFile = getDataFileName "sample" >>= readFile
Correspondingly, the .cabal
file for this mentions that
it's indefinite
and needs an implementation of
Dist.DataFiles
to use:
name: sample-library
indefinite: True
build-depends: base
exposed-modules: Sample.Library
required-signatures: Dist.DataFiles
I can later on write an application that uses this library:
module Main where
import Sample.Library
main = getFile >>= putStrLn
In order to compile this, I need to tell sample-library
which implementation of Dist.DataFiles
to use. For example,
I can tell it to use the naïve implementation above by
writing a cabal file like this:
name: sample-executable
build-depends: base,
sample-library (Dist.DataFiles.Here as Dist.DataFiles)
If I did not provide an implementation of Dist.DataFiles
for
sample-library
, then this would not compile, because sample-library
would still be indefinite.