【问题标题】:Why does ghci outputs (Num a) => a for :t 4 and not (Ord a) => a?为什么 ghci 输出 (Num a) => a for :t 4 而不是 (Ord a) => a?
【发布时间】:2016-10-31 22:54:11
【问题描述】:

当我在 ghci 中输入 :t 4 时,我得到了

Prelude> :t 4
4 :: Num t => t

我理解为什么4 不仅是一个 Int 或一个 Integer,而且它是自下而上推断的,但我不明白为什么 4 没有显示为 Ord t => t 或更正确的是这样的:

4 :: (Ord t || Num t) => t

因为4 既是Ord 又是NumOrdNum 没有连接...

那么为什么:t 4 只输出Num

【问题讨论】:

  • 这在haskell report中有描述
  • 假设我给4 类型Ord t => t。现在我注意到BoolOrd 的一个实例。因此4 :: Bool4 :: Bool 应该是 True 还是 False,为什么?
  • @Lee Btw,关于类型默认规则有类似的问题:stackoverflow.com/questions/39251728/… 我试图回答并理解报告,但仍然没有明确的看法。也许更有经验的 Haskell 用户可以提供帮助:)

标签: haskell types type-inference typeclass


【解决方案1】:

并非所有具有Num 实例的类型也具有Ord 实例,您只需要NumfromInteger 部分即可拥有Haskell 具有的重载数字文字。例如,来自Data.ComplexComplex 有一个Num 实例,但没有Ord。在这种情况下,4不是Ord

ghci> import Data.Complex
ghci> let x = 1 :: Complex Double
ghci> let y = 2 :: Complex Double
ghci> x < y
<interactive>
    * No instance for (Ord (complex Double)) arising from use of `<'
    * In the expression: x < y
      In the equation for `it': it = x < y
ghci>

正如@Lee 所说,这是report 中概述的行为。

【讨论】:

  • 请注意,您解释了为什么类型不是(Ord t, Num t) =&gt; t,而不是为什么不是(Ord t || Num t) =&gt; t(这不是有效的语法,但我认为它的意思是说“t可能是Ord Num)。
  • @sepp2k 这是真的——我没有这样解释||。也就是说,我想我间接回答了这个......
  • 好的,谢谢。 @Lee 提供的链接中带有 fromIntegral 的东西非常有帮助。更有帮助的是3.4.3 部分的链接。所以当我写(3&lt;4): 来推断4 的实际类型时,编译器必须找到满足(Num t, Ord t) =&gt; t 的类型,它可以是IntIntegerFloatDouble 之一(甚至更多与外部模块)。这是模棱两可的,会产生错误。但是对于 Num,这些歧义通过默认为(在这种情况下)整数来解决。
猜你喜欢
  • 1970-01-01
  • 2019-08-13
  • 1970-01-01
  • 1970-01-01
  • 2020-05-01
  • 1970-01-01
  • 2011-04-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多