什么是“ Integer类型的适当值”,我可以写一个吗?也是新类型

Haskell 2010报告6.4.1节说

  

整数文字表示函数fromInteger在类型Integer的适当值上的应用。

“适当的价值”是什么样的?我可以在源代码Haskell中编写它吗?我当然可以写

x :: Integer
x = 4

但是那个等式等于

x = (fromInteger 4) :: Integer

编辑:避免无限回归,可能应该是

x = (fromInteger 4?) :: Integer

其中4?是类型4上的神秘值Integer

因此它正在选择Integer的{​​{1}}重载。文字的类型(在原始fromInteger中)仍为x = 4,而不是4 :: Num a => a

我在考虑这个Integer的问题:

newtype

如果我要求{-# 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 ,我会看到show y;如果我问MkAge 4,我会看到普通的show x。那么,4是否有一些不可见的构造函数?

Integer的补充q:因为我可以写newtype,构造函数z = (4 + 5 :: Age)真的必要吗?

MkAge

如果我想要一些前缀,似乎也可以正常工作。

hg999520 回答:什么是“ Integer类型的适当值”,我可以写一个吗?也是新类型

  

我可以在Haskell源代码中写它吗?

排序。

您可以编写4 :: Integer,但是4已经是fromInteger的“适当值”的应用程序。 :: Integer仅为fromInteger选择适当的重载。该应用程序的类型为Integer,因此它可以像魔术般的单义文字一样工作。

newtype Age = MkAge Int  deriving (Num,Eq,Ord,Show)

您现在可以写4 :: Age了,可以。这与Show的操作无关。您可以编写自己的Show实例,该实例打印纯4而不是MkAge 4。这是所有内置类型的Show实例的工作方式。以下是特定于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’

如您所见,IntInteger有数据构造函数(它们不是 不可见!)。对于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。它是善意的构造函数对诚实的单态文字的应用。 Integer呢?

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’

因此Integer构造函数对程序员是隐藏的(我想是故意的)。但是,如果您自己编写GHC.Integer.Type,则可以使用GHC.Integer.Type.S# 3#。它的类型为Integer,并且还是诚实的单态文字的真实构造函数的应用。

,

4 :: Integer是这样的值; 4 :: Int不是。不要将文字4与它在源代码中表示的实际值系列混淆。

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

当您在声明x = 4确实是类型x的值后写Integer时,编译器会为您的代码“提取”值4 :: Integer从文字上看。


MkAge是类型检查所必需的。 mkAge2 4的工作正是因为您已经为Num定义(或至少派生了)Age的实例,这需要定义fromInteger :: Integer -> AgemkAge2隐式调用fromInteger上的4以返回MkAge 4,并且那个是传递给mkAge2的值。因此,您仍然需要MkAge,而不必显式使用使用

本文链接:https://www.f2er.com/3145295.html

大家都在问