Difference between type and newtype in Haskell
From the book Programming in Haskell ( http://www.cs.nott.ac.uk/~gmh/book.html ) the parser is defined like this:
> type Parser a = String -> [(a,String)]
However, from the sample code ( http://www.cs.nott.ac.uk/~gmh/Parsing.lhs ) the definition is slightly different.
> newtype Parser a = P (String -> [(a,String)])
I found a difference from this page: https://wiki.haskell.org/Type#Type_and_newtype as follows:
introduces a type synonym and uses the same data constructors. newtype introduces type renaming and requires you to provide new constructors.
Here are my questions:
- For the new type, why is it
P(...)
used to include content? - This requires creating a new constructor newtype, but I don't seem to find it in the sample code. How do I define a constructor for newtype? Can't you provide it?
source to share
For the new type, why is it
P(...)
used to include content?
Any declared type newtype
must have one constructor. In this case, this constructor has a name P
and its type
P :: (String -> [(a, String)]) -> Parser a
You can also use notation syntax, so it will be equivalent to
newtype Parser a = P { runParser :: String -> [(a, String)] }
Or if you must use a type data
(in which case the wrapper won't be optimized at runtime as easily) it would be very similar:
data Parser a = P { runParser :: String -> [(a, String)] }
It is required to provide a new constructor newtype, but I didn't seem to find it in the sample code. How do I define a constructor for newtype? Is it ok not to provide one?
As mentioned above, constructor c newtype Parser
has a name P
, and there must be exactly one constructor for newtype
.
For a more detailed description, the keyword type
creates a simple alias. For example, String
defined as
type String = [Char]
You can use String
in any function that accepts [Char]
, and you can use [Char]
in any function that accepts String
. Since it FilePath
is defined as
type FilePath = String
Then you can use FilePath
wherever you use String
and therefore wherever you use [Char]
and vice versa. They are just names to abbreviate more complex types. I would say that in practice it is more common to use newtype
, rather than type
, except in very simple cases, simply because it allows the type system to be used more efficiently in your software. There are also disadvantages to type
s, since you need language extensions to use them in declarations instance
, and they must always be fully applied in other expressions. The downsides newtype
are that you have to wrap / unwrap them a lot, but this can be a big advantage when dealing with really complex programs.
source to share