多参数newtype用元组伪造?

gat*_*ado 10 haskell newtype

这是一个愚蠢的问题,一直困扰着我.为什么我不能写一个包含多个参数的newtype,

newtype A = A Int Int
Run Code Online (Sandbox Code Playgroud)

虽然元组版本很好吗?

newtype A = A (Int, Int)
Run Code Online (Sandbox Code Playgroud)

前者在模式匹配等方面要好得多.

n. *_* m. 11

newtype A = A Int创建一个同构的类型Int.也就是说,它的行为与Intwrteg 完全相同bottom,但名称不同.

data A = A Int此形成对比的是,创造了一种与Int不同的提升类型.还有一个不在的增值Int:( A undefined与之不同undefined::A).

现在,newtype A = A (Int, Int)创建一个同构的类型(Int, Int).顺便说一句,这恰恰是什么data A = A Int Int.

因此,如果我们承认newtype A = A Int Int相同newtype A = A (Int, Int),我们有什么? newtype A = A Int Int相当于newtype A = A (Int, Int)等于data A = A Int Int.

newtype A = A Int Int相当于data A = A Int Int(newtype在这种情况下是多余的),但是

newtype A = A Int等同于data A = A Int(这是具有整点newtype在第一位置).

因此,我们必须得出结论,newtype A = A Int Int相当于newtype A = A (Int, Int)创建冗余和不一致,我们最好不要允许它.

可能没有办法给出newtype A = A Int Int一些没有这些不一致的其他含义(否则我会发现并使用它;)


C. *_*ann 7

因为newtype粗略地讲,它type在运行时和data编译时一样工作.每个data定义都增加了一个额外的间接层 - 在正常情况下,这意味着另一个不同的地方,可以将某些东西留作thunk - 围绕它所拥有的值,而newtype不是.a上的"构造函数" newtype基本上只是一种幻觉.

任何将多个值组合成一个或者在多个案例之间进行选择的东西,必然会引入一个间接层来表达,因此逻辑解释newtype A = A Int Int将是两个断开连接的Int值,没有任何"将它们保持在一起".在这种情况下的不同之newtype A = A (Int, Int)处在于元组本身增加了额外的间接层.

与此data A = A Int Int对比data A = A (Int, Int).前者A在两个Ints 周围添加一个层(构造函数),而后者在元组周围添加相同的层,它本身在Ints 周围添加了一个层.

每一层间接通常也会添加一个可以something的地方,所以考虑每种形式的可能情况,在哪里?代表非最低价值:

  • 对于newtype A = A (Int, Int):?,(?, ?),(?, ?),(?, ?)

  • 对于data A = A Int Int:?,A ? ?,A ? ?,A ? ?

  • 对于data A = A (Int, Int):?,A ?,A (?, ?),A (?, ?),A (?, ?)

从上面可以看出,前两个是等价的.


最后一点,这里有一个有趣的例子,说明了newtype与众不同之处data.考虑这些定义:

data D = D D deriving Show
newtype N = N N deriving Show
Run Code Online (Sandbox Code Playgroud)

哪些可能的值,包括所有可能的,s,都可以做到?您认为以下两个值是什么?

d = let (D x) = undefined in show x
n = let (N x) = undefined in show x
Run Code Online (Sandbox Code Playgroud)

加载它们在GHC中找出来!