Haskell 为什么我会得到;类别编号a,其中;而不是;等级(等式a,显示a)=>;数字a";?
我学哈斯克尔。我将命令发送到ghci:Haskell 为什么我会得到;类别编号a,其中;而不是;等级(等式a,显示a)=>;数字a";?,haskell,ghci,Haskell,Ghci,我学哈斯克尔。我将命令发送到ghci::info Num ghci> :info Num class Num a where (+) :: a -> a -> a (*) :: a -> a -> a (-) :: a -> a -> a negate :: a -> a abs :: a -> a signum :: a -> a fromInteger :: Integer -> a -- Defined in `GHC.Nu
:info Num
ghci> :info Num
class Num a where
(+) :: a -> a -> a
(*) :: a -> a -> a
(-) :: a -> a -> a
negate :: a -> a
abs :: a -> a
signum :: a -> a
fromInteger :: Integer -> a
-- Defined in `GHC.Num'
instance Num Integer -- Defined in `GHC.Num'
instance Num Int -- Defined in `GHC.Num'
instance Num Float -- Defined in `GHC.Float'
instance Num Double -- Defined in `GHC.Float'
我希望看到这样的东西:class(Eq a,Show a)=>numa
,但我看到class numa其中
。我很惊讶。。。好的,我打开Hoogle并尝试查找Num
类类型的信息。我知道了。我在搜索结果的第一条记录中看到类(Eq a,Show a)=>Num a
。但当我打开来源时,我看到:
-- | Basic numeric class.
--
-- Minimal complete definition: all except 'negate' or @(-)@
class Num a where
为什么我得到的是
类Num a而不是类(Eq a,Show a)=>Num a
?显示类(Eq a,Show a)=>Num a的黑客行为可能是一个bug,但是numa
确实没有理由要求Eq a
和Show a
我认为Hoogle的搜索索引非常旧
您可以看到,在这些提交的ghc
中,从Num
中删除了Eq
和Show
超类
因此,我认为这是Hoogle搜索结果与实际链接之间不一致的原因。 < P> <代码> Num <代码>是你可以基本上添加和乘法的东西。我认为(+)
应该是一个,但政府没有提到它
你会加法和乘法吗?当然可以,如果函数产生一个数字
haskell中没有函数的Eq
和Show
实例,这就是为什么Num
不需要这些约束
现在你也想要Ord
containt?复数是Num
s,但没有顺序能像实数那样保持相同的规律。这里有一个Num
实例,你不能合理地定义Eq
或Show
实例-
instance Num r => Num (a -> r) where
(f + g) a = f a + g a
(f - g) a = f a - g a
(f * g) a = f a * g a
abs f = abs . f
signum f = signum . f
fromInteger = const . fromInteger
这里有一个稍微深奥一点的-
data State s a = State { runState :: s -> (a, s) }
instance Functor (State s) where
fmap f h = State $ \s -> let (a, s') = runState h s in (f a, s')
instance Num a => Num (State s a) where
h + k = State $ \s -> let (a, s') = runState h s
(b, s'') = runState k s'
in (a + b, s'')
h * k = State $ \s -> let (a, s') = runState h s
(b, s'') = runState k s'
in (a * b, s'')
negate = fmap negate
abs = fmap abs
signum = fmap signum
fromInteger n = State $ \s -> (fromInteger n, s)
它具有不寻常的特性,即加法和乘法是不可交换的(因为两个参数中的每一个都可以任意修改状态,并且状态可以与返回的结果任意混合),但除此之外,它是Num
的有效实例
数学旁注:Num
类通常对代数结构进行建模,称为代数结构,具有交换加法和(不一定是交换的)乘法,它们满足一些兼容性规则
在这种情况下,加法不是交换的,因此它不能是环。它甚至不是a(这是一个去掉了很多限制的环),因为它不满足分配定律。这就提出了一个问题——它是否遵循任何合理众所周知的代数结构的规律
这两个都是更普遍现象的示例,即任何应用程序都可以通过使用fmap
和liftA2
提升到Num
的实例-
instance (Num a, Applicative f) => Num (f a) where
(+) = liftA2 (+)
(*) = liftA2 (*)
abs = fmap abs
signum = fmap signum
negate = fmap negate
fromInteger = pure . fromInteger
这是一个我非常喜欢的事实。我不同意你说的“真的没有理由”。@Bush好吧,你为什么认为Num
应该内在地要求Eq
和Show
?@Bush纯粹是为了算术运算,比如Num
是;没有必要使用Eq
和Show
,因为它们都与加法、乘法或减法无关。而是由各个实现来处理。您在Functor
或Monad
类型类上看不到Eq
或Show
,原因与Haskell 98和Haskell 2010所指定的相同,可能是错误的。@Bergi谢谢您。我看到“-class Num a=>位a where”和“+class(Eq a,Num a)=>位a where”。据我所知-“-”表示删除,“+”表示添加。所以我看到删除了“class Num a=>Bits a where”代码行,并添加了“class(Eq a,Num a)=>Bits a where”。我说得对吗?@Bush说得对,最肯定的是因为Bits
在Num
之后应该仍然是相等的,是不是不再是了。加法、乘法和否定(因此减法)。这可能只是GHC偏离了官方语言的定义。这应该是选定的答案。