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?
+3


source to share


1 answer


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.

+7


source







All Articles