[Haskell-beginners] question, chapter 10 Real World Haskell
Michael Mossey
mpm at alumni.caltech.edu
Sat Apr 11 12:37:53 EDT 2009
Daniel Fischer wrote:
>
> In a real library, the constructor Parse would not be exported, to allow later changing
> the implementation of the Parse type without breaking user code.
> So user code like parseByte cannot access the constructor and must use the exported API
> (getState, putState, identity, bail, ...).
thanks for the point, I get it. One other question. Later in the chapter they define
peekByte as follows:
-- file: ch10/Parse.hs
peekByte :: Parse (Maybe Word8)
peekByte = (fmap fst . L.uncons . string) <$> getState
Here they are accessing the 'string' field of the state. So whomever writes this
function needs to have the accessor functions. At this point I'm wondering how much
state is really getting hidden. Or maybe peekByte would only be written inside the
original library.
I was just playing around and discovered you can choose to export the accessor
functions or not. Let's say we have
--------
module Mod where
data What = What { acc :: Int64 }
--------
now in a separate module we write:
-------------------
-- All fine:
import Mod
x1 = What 3
x2 = What { acc = 3 }
x3 = acc x1
---------------
Now we revisit the first module and write
module Mod ( What(What) ) where
Now,
import Mod
x1 = What 3 -- Fine
x2 = What { acc = 3 } -- Error
x3 = acc x1 -- Error
So apparently this exports the constructor but not the accessor fields. The item can
be constructed in the normal way, but not in record syntax way.
Finally
module Mod ( What(acc) ) where
--> This exports the accessors which can be used to access, but not to construct
module Mod (What(..)) where
--> export everything
So the lesson is, if we are going to allow users to write functions like peekByte, we
have to export the accessor functions, but not necessarily any constructors.
More information about the Beginners
mailing list