Real world haskell says:
we will hide the details of our parser type using a newtype declaration
I don't get how we can hide anything using the newtype. Can anyone elaborate? What are we trying to hide and how do we do it.
data ParseState = ParseState {
string :: L.ByteString
, offset :: Int64 -- imported from Data.Int
} deriving (Show)
newtype Parse a = Parse {
runParse :: ParseState -> Either String (a, ParseState)
}
The idea is to combine modules + newtypes to keep people from seeing the internals of how we implement things.
-- module A
module A (A, toA) where -- Notice we limit our exports
newtype A = A {unA :: Int}
toA :: Int -> A
toA = -- Do clever validation
-- module B
import A
foo :: A
foo = toA 1 -- Must use toA and can't see internals of A
This prevents from pattern matching and arbitrarily constructing A
. This let's our A
module make certain assumptions about A
and also change the internals of A
with impunity!
This is particularly nice because at runtime the newtype
s are erased so there's almost no overhead from doing something like this
You hide details by not exporting stuff. So there's two comparisons to make. One is exported vs. not exported:
-- hidden: nothing you can do with "Parse a" values -- though
-- you can name their type
module Foo (Parse) where
newtype Parse a = Parse { superSecret :: a }
-- not hidden: outsiders can observe that a "Parse a" contains
-- exactly an "a", so they can do anything with a "Parse a" that
-- they can do with an "a"
module Foo (Parse(..)) where
newtype Parse a = Parse { superSecret :: a }
The other is more subtle, and is the one RWH is probably trying to highlight, and that is type
vs. newtype
:
-- hidden, as before
module Foo (Parse) where
newtype Parse a = Parse { superSecret :: a }
-- not hidden: it is readily observable that "Parse a" is identical
-- to "a", and moreover it can't be fixed because there's nothing
-- to hide
module Foo (Parse) where
type Parse a = a
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With