let x-6ren">
gpt4 book ai didi

haskell - 为什么在Num中没有定义(/)时编译 "1/2"?

转载 作者:行者123 更新时间:2023-12-05 01:01:42 24 4
gpt4 key购买 nike

对不起,一个新手问题,但我真的不明白重载的值:

GHCi, version 7.8.3: http://www.haskell.org/ghc/  :? for help
Prelude> let x = 1
Prelude> let y = 2

两者 xy有型 Num a => a .但是没有 (/)定义于 Num !那么为什么表达式 x / y类型检查?
Prelude> x / y
0.5
(/)在类 Fractional 中定义.是否有来自 Num 的隐式转换至 Fractional ?

UPD :

所以,正如预期的那样,我得到了人们在 x / y 中声称的答案。 a专于 Fractional a => a .

我创建了自己的数字层次结构:
data MyInt = MyInt Integer deriving Show
data MyDouble = MyDouble Double deriving Show

class MyNum a where
(+#) :: a -> a -> a -- + renamed to +# to avoid collision with standard +
myFromInteger :: MyNum a => Integer -> a

class MyNum a => MyFractional a where
(/#) :: a -> a -> a

instance MyNum MyInt where
(MyInt a) +# (MyInt b) = MyInt (a + b)
myFromInteger i = MyInt i

instance MyNum MyDouble where
(MyDouble a) +# (MyDouble b) = MyDouble (a + b)
myFromInteger i = MyDouble (fromInteger i)

instance MyFractional MyDouble where
(MyDouble a) /# (MyDouble b) = MyDouble (a / b)

如果asnwers中的所有内容都是真的,类似的代码 Num替换为 MyNum也应该工作。但是ghci报错:
Prelude> :load myint.hs
*Main> let x = myFromInteger 1
*Main> let y = myFromInteger 2
*Main> x /# y

<interactive>:14:1:
No instance for (MyFractional a0) arising from a use of `it'
The type variable `a0' is ambiguous
Note: there is a potential instance available:
instance MyFractional MyDouble -- Defined at myint.hs:19:10
In the first argument of `print', namely `it'
In a stmt of an interactive GHCi command: print it

最佳答案

看来您使用的是较新版本的 ghci,默认情况下,该版本具有 NoMonomorphismRestriction启用。在这种情况下 xy确实有类型Num a => a :

Prelude> :set -XNoMonomorphismRestriction
Prelude> let x = 1
Prelude> let y = 2
Prelude> :t x
x :: Num a => a

而这种类型,由于它是多态的,专门用于 Fractional a => a当您评估时 x/y :
Prelude> :t x/y
x/y :: Fractional a => a

NumFractional 的父类(super class)任何 Fractional类型也是 Num类型,因此专门针对 x 的类型和 yFractional a => a是可能的。这与做类似的事情没有什么不同:
($) = id :: (a -> b) -> (a -> b)

函数 $只是 id :: c -> c 的专长哪里 c = a -> b .在您的情况下,您正在专门化受约束的类型,并且可以专门用子类替换父类(即更通用的更具体的约束),所以 Fractional a => aNum a => a的专业.

当 ghci 必须输出结果时,它必须选择 / 的实现。运算符才能计算结果,因此它必须将类型实例化为具体类型。这是由 defaulting 完成的,因此执行的操作是 Double 的操作实例,但可以使用 default 更改它们宣言。

请注意,默认值仅适用于内置类。引用上面的链接:

Ambiguities in the class Num are most common, so Haskell provides another way to resolve them---with a default declaration:

default (t1 , ... , tn)

where n>=0, and each ti must be a type for which Num ti holds. In situations where an ambiguous type is discovered, an ambiguous type variable, v, is defaultable if:

  • v appears only in constraints of the form C v, where C is a class, and at least one of these classes is a numeric class, (that is, Num or a subclass of Num), and
  • all of these classes are defined in the Prelude or a standard library (Figures 6.2--6.3, pages -- show the numeric classes, and Figure 6.1, page , shows the classes defined in the Prelude.)

关于haskell - 为什么在Num中没有定义(/)时编译 "1/2"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27847459/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com