Haskell中平凡数转换的问题

Haskell中平凡数转换的问题,haskell,numbers,type-conversion,ghci,Haskell,Numbers,Type Conversion,Ghci,我试图编写一个简单的函数来删除数字的最后一位并返回数字的其余部分 dropLastDigit :: (Integral b) => b -> b dropLastDigit x = (quot x 10) * (floor $ logBase 10 x) 但是,当我尝试将其加载到ghci中时,我得到: Could not deduce (Floating b) arising from a use of ‘logBase’ from the context (Integra

我试图编写一个简单的函数来删除数字的最后一位并返回数字的其余部分

dropLastDigit :: (Integral b) => b -> b
dropLastDigit x = (quot x 10) * (floor $ logBase 10 x)
但是,当我尝试将其加载到ghci中时,我得到:

Could not deduce (Floating b) arising from a use of ‘logBase’
    from the context (Integral b)
      bound by the type signature for
                 dropLastDigit :: Integral b => b -> b
      at haskelljokes.hs:6:18-39
    Possible fix:
      add (Floating b) to the context of
        the type signature for dropLastDigit :: Integral b => b -> b
    In the second argument of ‘($)’, namely ‘logBase 10 x’
    In the expression: floor $ logBase 10 x
    In an equation for ‘dropLastDigit’:
        dropLastDigit x = floor $ logBase 10 x
但是,在ghci中运行此代码:

:t(quot 101 10)*(地板$logBase 10 101)

产生:
(quot 101 10)*(floor$logBase 10 101)::Integral a=>a


我的问题是,我做错了什么?为什么(相同的代码?)在ghci中工作?

将您的功能更改为

dropLastDigit :: (Integral b) => b -> b
dropLastDigit x = (quot x 10) * (floor $ logBase 10 (fromIntegral x))
您在GHCi中运行的代码不相同。您已将
x
替换为
101
。对于
Integral
类中的任何类型
b
,函数中的
x
被注释(通过类型签名)为
b
,但是
logBase
需要
Floating
类中的某些内容


另一方面,文本
101
的类型为
Num a=>a
,即,它重载并可用于任何数字类型。因此,GHCi可以在第一次出现时在类型
Integer
处使用它,作为
quot
的参数,在第二次出现时作为
Double
的参数,将函数更改为

dropLastDigit :: (Integral b) => b -> b
dropLastDigit x = (quot x 10) * (floor $ logBase 10 (fromIntegral x))
您在GHCi中运行的代码不相同。您已将
x
替换为
101
。对于
Integral
类中的任何类型
b
,函数中的
x
被注释(通过类型签名)为
b
,但是
logBase
需要
Floating
类中的某些内容


另一方面,文本
101
的类型为
Num a=>a
,即,它重载并可用于任何数字类型。因此,GHCi可以在第一次出现时在类型
Integer
处使用它,作为
quot
的参数,在第二次出现时作为
Double
的参数,作为
logBase

的参数,它是不相同的。您可以很容易地检查这一点:

ghci> let value101 = 101 :: Integral b => b
ghci> let value10  = 10  :: Integral b => b
ghci> (quot value101 value10) * (floor $ logBase value10 value101)

<interactive>:7:28:
    Could not deduce (RealFrac s0) arising from a use of `floor'
    from the context (Integral a)
      bound by the inferred type of it :: Integral a => a
      at <interactive>:7:1-60
    The type variable `s0' is ambiguous
    Note: there are several potential instances:
      instance RealFrac Double -- Defined in `GHC.Float'
      instance RealFrac Float -- Defined in `GHC.Float'
      instance Integral a => RealFrac (GHC.Real.Ratio a)
        -- Defined in `GHC.Real'
    In the expression: floor
    In the second argument of `(*)', namely
      `(floor $ logBase value10 value101)'
    In the expression:
      (quot value101 value10) * (floor $ logBase value10 value101)

-- even more...
但是,如果要将
12345
转换为
12340
,则只需在之后乘以10即可:

dropLastDigit x = 10 * (x `div` 10)

不一样。您可以很容易地检查这一点:

ghci> let value101 = 101 :: Integral b => b
ghci> let value10  = 10  :: Integral b => b
ghci> (quot value101 value10) * (floor $ logBase value10 value101)

<interactive>:7:28:
    Could not deduce (RealFrac s0) arising from a use of `floor'
    from the context (Integral a)
      bound by the inferred type of it :: Integral a => a
      at <interactive>:7:1-60
    The type variable `s0' is ambiguous
    Note: there are several potential instances:
      instance RealFrac Double -- Defined in `GHC.Float'
      instance RealFrac Float -- Defined in `GHC.Float'
      instance Integral a => RealFrac (GHC.Real.Ratio a)
        -- Defined in `GHC.Real'
    In the expression: floor
    In the second argument of `(*)', namely
      `(floor $ logBase value10 value101)'
    In the expression:
      (quot value101 value10) * (floor $ logBase value10 value101)

-- even more...
但是,如果要将
12345
转换为
12340
,则只需在之后乘以10即可:

dropLastDigit x = 10 * (x `div` 10)

谢谢你的明确答复。这确实有助于提醒我仔细思考我的打字课。向上投票。泽塔击败了你,所以他得到了接受。谢谢你明确的回答。这确实有助于提醒我仔细思考我的打字课。向上投票。泽塔打败了你,所以他得到了接受。