Haskell 什么是「;“整数”类型的适当值;我能写一本吗;还有新类型

Haskell 什么是「;“整数”类型的适当值;我能写一本吗;还有新类型,haskell,typeclass,newtype,Haskell,Typeclass,Newtype,Haskell 2010报告第6.4.1节说 整数文本表示函数从整数到类型为整数的适当值的应用 “适当价值”是什么样的?我可以用Haskell的源代码写吗?我当然会写 x :: Integer x = 4 但这个等式相当于 x = (fromInteger 4) :: Integer 编辑:hmm以避免可能出现的无限回归 x = (fromInteger 4?) :: Integer 其中4?是类型Integer处的神秘值4 因此它选择了Integer重载fromInteger。文本的类型

Haskell 2010报告第6.4.1节说

整数文本表示函数
从整数
到类型为
整数
的适当值的应用

“适当价值”是什么样的?我可以用Haskell的源代码写吗?我当然会写

x :: Integer
x = 4
但这个等式相当于

x = (fromInteger 4) :: Integer
编辑:hmm以避免可能出现的无限回归

x = (fromInteger 4?) :: Integer
其中
4?
是类型
Integer
处的神秘值
4

因此它选择了
Integer
重载
fromInteger
。文本的类型(在原始
x=4
中)仍然是
4::Num a=>a
,它不是类型
整数

我在想这个wrt
newtype
s:

{-# LANGUAGE  GeneralisedNewtypeDeriving  #-}

newtype Age = MkAge Int  deriving (Num, Eq, Ord, Show)
                        -- fromInteger is in Num
y :: Age
y = 4  
z = (4 + 5 :: Age)      -- no decl for z, inferred :: Age
如果我要求
显示y
我会看到
MkAge 4
;如果我要求
显示x
我会看到普通的
4
。那么,对于
Integer
s,是否存在一些不可见的构造函数

对于
newtype
s的补充q:既然我能写
z=(4+5::Age)
那么构造函数
MkAge
真的有必要吗

mkAge2 :: Age -> Age
mkAge2 = id

w = mkAge2 4

mkAge3 :: Integer -> Age
mkAge3 = fromInteger

u = mkAge3 4

如果我想要前缀的话,它似乎也可以工作。

4::Integer
就是这样一个值<代码>4::Int
不是。不要将文本
4
与它在源代码中表示的实际值族混淆

4
本身具有多态类型
Num a=>a
,这意味着在正确的上下文中,可以从中“提取”类型为
4::Integer
的值。这样的上下文是对
fromInteger
的调用,因为它需要一个
Integer
类型的值作为参数,而不是
Num a=>a
类型的值

当您在声明
x
确实是
Integer
类型的值之后编写
x=4
时,编译器负责从文本中“提取”您的值
4::Integer



MkAge
是进行类型检查所必需的
mkAge2 4
的工作原理正是因为您为
Age
定义了(或至少派生了)一个
Num
实例,这需要定义
fromInteger::Integer->Age
mkAge2
隐式调用
4
上的
fromInteger
返回
mkage4
,这是传递给
mkAge2
的值。因此,您仍然需要
MkAge
,您不必显式地使用它。

4::Integer
就是这样一个值<代码>4::Int不是。不要将文本
4
与它在源代码中表示的实际值族混淆

4
本身具有多态类型
Num a=>a
,这意味着在正确的上下文中,可以从中“提取”类型为
4::Integer
的值。这样的上下文是对
fromInteger
的调用,因为它需要一个
Integer
类型的值作为参数,而不是
Num a=>a
类型的值

当您在声明
x
确实是
Integer
类型的值之后编写
x=4
时,编译器负责从文本中“提取”您的值
4::Integer


MkAge
是进行类型检查所必需的
mkAge2 4
的工作原理正是因为您为
Age
定义了(或至少派生了)一个
Num
实例,这需要定义
fromInteger::Integer->Age
mkAge2
隐式调用
4
上的
fromInteger
返回
mkage4
,这是传递给
mkAge2
的值。所以您仍然需要
MkAge
,您不必显式地使用它

我可以用Haskell的源代码写吗

有点

您可以将
4::Integer
写入,但是
4
已经是
fromInteger
到“适当值”的应用程序<代码>::Integer仅为
fromInteger
选择适当的重载。但是,应用程序的类型为
Integer
,因此它可以像神奇的单态文字一样工作

您现在可以编写
4::Age
,这样就可以了。这与
Show
的功能无关。您可以编写自己的
Show
实例来打印普通的
4
,而不是
MkAge 4
。这就是所有内置类型的
显示
实例的工作方式。以下是GHC特有的,其他实现可能有不同的细节,但一般原则可能是相同的

Prelude> :i Int
data Int = GHC.Types.I# Int#    -- Defined in ‘GHC.Types’
Prelude> :i Integer
data Integer
  = integer-gmp-1.0.2.0:GHC.Integer.Type.S# Int#
  | integer-gmp-1.0.2.0:GHC.Integer.Type.Jp# {-# UNPACK #-}integer-gmp-1.0.2.0:GHC.Integer.Type.BigNat
  | integer-gmp-1.0.2.0:GHC.Integer.Type.Jn# {-# UNPACK #-}integer-gmp-1.0.2.0:GHC.Integer.Type.BigNat
    -- Defined in ‘integer-gmp-1.0.2.0:GHC.Integer.Type’
正如您所看到的,
Int
Integer
都有数据构造函数(它们不是那么不可见!)。我们可以使用一个用于
Int
没有问题

Prelude> :set -XMagicHash
Prelude> :t 3#
3# :: GHC.Prim.Int#
Prelude> :t GHC.Types.I# 3#
GHC.Types.I# 3# :: Int
Prelude> show 3
"3"
Prelude> show $ GHC.Types.I# 3#
"3"
好的,我们已经用构造函数构建了一个
Int
,它不会干扰将它显示为一个简单的
3
一点点。它是真正的构造函数对诚实的单态文字的应用。那整数呢

Prelude> GHC.Integer.Type.S# 3#

<interactive>:16:1: error:
    Not in scope: data constructor ‘GHC.Integer.Type.S#’
    No module named ‘GHC.Integer.Type’ is imported.
Prelude>
Prelude>GHC.Integer.Type.S#3#
:16:1:错误:
不在范围内:数据构造函数“GHC.Integer.Type.S#”
未导入名为“GHC.Integer.Type”的模块。
序曲>

Prelude>:m+GHC.Integer.Type
:错误:
无法加载模块“GHC.Integer.Type”
它是“integer-gmp-1.0.2.0”包中的隐藏模块
因此
Integer
构造函数对程序员是隐藏的(我想是有意的)。但是如果您编写的是
GHC.Integer.Type
本身,则可以使用
GHC.Integer.Type.S#3
。它的类型为
Integer
,也是真正的构造函数对诚实的单态文字的应用

我可以用Haskell的源代码写吗

有点

你可以写<
Prelude> GHC.Integer.Type.S# 3#

<interactive>:16:1: error:
    Not in scope: data constructor ‘GHC.Integer.Type.S#’
    No module named ‘GHC.Integer.Type’ is imported.
Prelude>
Prelude> :m + GHC.Integer.Type

<no location info>: error:
    Could not load module ‘GHC.Integer.Type’
    it is a hidden module in the package ‘integer-gmp-1.0.2.0’