本文介绍了Haskell中type和newtype之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

摘自《 Haskell编程》( http://www.cs. nott.ac.uk/~gmh/book.html ),解析器的定义如下:

From the book Programming in Haskell (http://www.cs.nott.ac.uk/~gmh/book.html), a parser is defined as follows:

> type Parser a = String -> [(a,String)]

但是,从示例代码中( http://www.cs. nott.ac.uk/~gmh/Parsing.lhs ),定义有些不同.

However, from the sample code (http://www.cs.nott.ac.uk/~gmh/Parsing.lhs), the definition is a little bit different.

> newtype Parser a              =  P (String -> [(a,String)])

我发现此页面与众不同: https://wiki.haskell.org/Type#Type_and_newtype 如下:

I found the difference from this page:https://wiki.haskell.org/Type#Type_and_newtype as follows:

这是我的问题:

  1. 对于新类型,为什么使用P(...)括住内容?
  2. 它需要为新的构造函数提供newtype,但是我似乎没有从示例代码中找到一个.如何为newtype定义构造函数?不提供一个可以吗?
  1. For new type why P(...) is used to enclose the content?
  2. It requires to provide new constructor with newtype, but I don't seem to find one from the example code. How to define constructor for newtype? Is it OK not to provide one?

推荐答案

任何newtype声明的类型都必须具有单个构造函数.在这种情况下,构造函数的名称为P,其类型为

Any newtype declared type must have a single constructor. In this case that constructor is named P and its type is

P :: (String -> [(a, String)]) -> Parser a

您还可以使用记录语法,因此它等效于

You can also use record syntax, so it would be equivalent to

newtype Parser a = P { runParser :: String -> [(a, String)] }

或者,如果您要使用data类型(在这种情况下,包装程序在运行时不会轻易优化),则将非常相似:

Or if you were to use a data type (in which case the wrapper does not get optimized away at runtime as easily), it would be very similar:

data Parser a = P { runParser :: String -> [(a, String)] }

如上所述,newtype Parser的构造函数命名为P,并且newtype必须完全有一个构造函数.

As mentioned above, the constructor to the newtype Parser is named P, and there must be exactly one constructor for a newtype.

更多说明,type关键字构造一个简单的别名.例如,String被定义为

Some more clarification, the type keyword constructs a simple alias. For example, String is defined as

type String = [Char]

您可以在使用[Char]的任何函数中使用String,并且可以在使用String的任何函数中使用[Char].由于FilePath被定义为

You can use String in any function that takes [Char], and you can use [Char] in any function that takes String. Since FilePath is defined as

type FilePath = String

然后,您可以在任何使用String的地方使用FilePath,因此可以在任何使用[Char]的地方使用,反之亦然.这些只是用于简化更复杂类型的名称.我要说的是,在实践中,除了非常简单的情况外,使用newtype而不是type更为常见,这仅仅是因为它允许类型系统在您的软件中执行更多操作. type也有缺点,因为您需要语言扩展才能在instance声明中使用它们,并且必须始终将它们完全应用于其他表达式中. newtype的缺点是您必须包装很多/拆开它们,但是当使用真正复杂的程序时,这可能会带来更多好处.

Then you can use FilePath where ever you would use a String and thus anywhere you would use [Char], and vice versa. These are simply names for reducing more complicated types. I would say that in practice it's more common to use newtype rather than type except in very simple cases, simply because it allows the type system to enforce things more in your software. There are also disadvantages to types, since you need language extensions to use them in instance declarations, and they must always be fully applied in other expressions. The disadvantages of newtype is that you have to wrap/unwrap them a lot, but this can be more of a boon when working with truly complex programs.

这篇关于Haskell中type和newtype之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-14 12:44