title: Why is import of an abstract type not necessary, when using functions which work with values of that type
body: <p>Following the excercises in chapter 5 of Real World Haskell, I end up with Prettify.hs, which exports among other things an abstract type Doc and a rendering function compact, which is a function from Doc to String. Another file, PrettyJSON.hs exports renderJValue, which ends up giving me a Doc value. In my main, I import just renderJValue and compact, and use the output of the one as input to the other. I am confused why this works. I would think that it would also have been necessary to import the abstract Doc type. Can Haskell see that the two functions fit together without the Doc imported?</p>
  
  <p>For illustration, this is my Main.hs:</p>
  
  <pre><code>module Main where
  
  import System.IO
  import SimpleJSON (JValue(..))
  import PrettyJSON (renderJValue)
  import Prettify (compact)
  
  main = do
      let val = renderJValue $ JString "foo"
      putStrLn $ compact val
      getLine
  </code></pre>
  
  <p>which outputs</p>
  
  <pre><code>"foo"
  </code></pre>