问题描述
摘自《 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:
这是我的问题:
- 对于新类型,为什么使用
P(...)
括住内容? - 它需要为新的构造函数提供newtype,但是我似乎没有从示例代码中找到一个.如何为newtype定义构造函数?不提供一个可以吗?
- For new type why
P(...)
is used to enclose the content? - 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 type
s, 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之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!