【问题标题】:Num and Integral type classes - HaskellNum 和 Integral 类型类 - Haskell
【发布时间】:2015-09-07 13:30:47
【问题描述】:

我正在阅读 Type 类,Chapter 2 of Learn You Haskell For Great Good。我的问题是为什么 4 + 3.2 有效,但长度 [1, 2, 3, 4] + 3.2 无效,为什么我们需要在第二种情况下使用 fromIntegral 函数。 NumIntegral 类型类之间是否没有关系。如何找到一个类型的实例是哪些类?

【问题讨论】:

    标签: haskell typeclass


    【解决方案1】:

    在这种情况下,使用 ghci 检查类型,例如它会告诉您第一次输入:

    Prelude> :t 4 + 3.2
    4 + 3.2 :: Fractional a => a
    

    这里fromInteger 是隐式使用的(4)。

    在第二种情况下,您会遇到问题,length:: [a] -> Int(在较新的 GHC 中有点不同),3.2 仍然是 :: Fractional a => a(+):: Num a => a -> a -> a(它需要相同参数类型a) - 现在Int 不是Fractional 的实例,您会收到错误消息。


    如何找到一个类型是实例的类

    PS(原来的答案已经消失)- 最简单的方法是使用 GHCi 使用 :i 本身:

    Prelude> :i Int
    data Int = GHC.Types.I# GHC.Prim.Int#   -- Defined in ‘GHC.Types’
    instance Bounded Int -- Defined in ‘GHC.Enum’
    instance Enum Int -- Defined in ‘GHC.Enum’
    instance Eq Int -- Defined in ‘GHC.Classes’
    instance Integral Int -- Defined in ‘GHC.Real’
    instance Num Int -- Defined in ‘GHC.Num’
    instance Ord Int -- Defined in ‘GHC.Classes’
    instance Read Int -- Defined in ‘GHC.Read’
    instance Real Int -- Defined in ‘GHC.Real’
    instance Show Int -- Defined in ‘GHC.Show’
    

    但请记住,这将取决于加载的模块 - 例如,当您 import Test.QuickCheck 时,您会看到 Int 现在也是 Arbitrary 的实例:

    Prelude Test.QuickCheck> :i Int
    data Int = GHC.Types.I# GHC.Prim.Int#   -- Defined in ‘GHC.Types’
    instance Bounded Int -- Defined in ‘GHC.Enum’
    instance Enum Int -- Defined in ‘GHC.Enum’
    instance Eq Int -- Defined in ‘GHC.Classes’
    instance Integral Int -- Defined in ‘GHC.Real’
    instance Num Int -- Defined in ‘GHC.Num’
    instance Ord Int -- Defined in ‘GHC.Classes’
    instance Read Int -- Defined in ‘GHC.Read’
    instance Real Int -- Defined in ‘GHC.Real’
    instance Show Int -- Defined in ‘GHC.Show’
    instance [overlap ok] [safe] CoArbitrary Int
      -- Defined in ‘Test.QuickCheck.Arbitrary’
    instance [overlap ok] [safe] Arbitrary Int
      -- Defined in ‘Test.QuickCheck.Arbitrary’
    

    【讨论】:

      【解决方案2】:

      length 将其输出类型固定为Int(与3.2 不兼容)而不是任何Num。您正在寻找的功能是:

      genericLength :: Num i => [b] -> i
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多