很抱歉有新手问题,但我真的不明白重载值:
GHCi, version 7.8.3: http://www.haskell.org/ghc/ :? for help
Prelude> let x = 1
Prelude> let y = 2
Run Code Online (Sandbox Code Playgroud)
无论x和y有型Num a => a.但是没有(/)定义Num!那么为什么表达式x / y检查呢?
Prelude> x / y
0.5
Run Code Online (Sandbox Code Playgroud)
(/)在课堂上定义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)
Run Code Online (Sandbox Code Playgroud)
如果asnwers中的所有内容都为true,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
Run Code Online (Sandbox Code Playgroud)
您似乎正在使用更新版本的ghci,默认情况下已NoMonomorphismRestriction启用.在这种情况下x,y确实有类型Num a => a:
Prelude> :set -XNoMonomorphismRestriction
Prelude> let x = 1
Prelude> let y = 2
Prelude> :t x
x :: Num a => a
Run Code Online (Sandbox Code Playgroud)
这种类型,因为它是多态的,专门用于Fractional a => a评估时x/y:
Prelude> :t x/y
x/y :: Fractional a => a
Run Code Online (Sandbox Code Playgroud)
由于Num是类的超类Fractional的任何Fractional类型也是一种Num类型并且因此专门的类型x和y对Fractional a => a是可能的.这与做类似的事情没有什么不同:
($) = id :: (a -> b) -> (a -> b)
Run Code Online (Sandbox Code Playgroud)
该功能$只是一个特殊的id :: c -> c地方c = a -> b.在你的情况下,你是一个专门的约束类型,约束可以专门用子类替换父类(即更一般的更具体的约束),所以Fractional a => a是一个特殊的Num a => a.
当ghci中具有输出结果就必须选择一个实现了的/操作,以计算出结果,因此它必须实例化类型的具体类型.这是通过默认完成的,因此执行的操作是Double实例的操作,但可以使用default声明更改它们.
请注意,默认仅适用于内置类.引用上面的链接:
类
Num中的歧义是最常见的,因此Haskell提供了另一种解决方法 - 使用默认声明:Run Code Online (Sandbox Code Playgroud)default (t1 , ... , tn)其中
n>=0,每个ti必须是一个类型Num ti.在发现模糊类型的情况下,如果出现以下情况,则模糊类型变量v是可以违约的:
v仅出现在表单的约束中C v,其中C是一个类,并且这些类中的至少一个是数字类(即,Num或者是其子类Num),并且- 所有这些类都在一个
Prelude或一个标准库中定义(图6.2--6.3,页面 - 显示数字类,图6.1,页面,显示了Prelude中定义的类.)