Haskell中数字转换的问题 [英] problems with trivial number conversions in Haskell

查看:235
本文介绍了Haskell中数字转换的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am attempting to write a trivial function to drop the last digit of a number and return the rest of the number.

dropLastDigit :: (Integral b) => b -> b
dropLastDigit x = (quot x 10) * (floor $ logBase 10 x)

然而,当我尝试加载到ghci时,我得到:

however, when I try to load this into ghci, I get:

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中运行这段代码:

However, running this code in ghci:

:t(101 10)*(floor $ logBase 10 101)

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

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

My question is, what am I doing wrong? And why is (the identical code?) working in ghci?

推荐答案

这不完全相同。您可以轻松查看:

It's not identical. You can check this easily:

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...

问题是 10 101 有类型 Num a =>一个,无论你在哪里使用它们。因此 logBase 10 101 将它们与默认的小数实例( Double c>),而 quot 将它们与默认的 Integral 实例一起使用。

The problem is that both 10 and 101 have type Num a => a, regardless of where you use them. So logBase 10 101 used them with the default Fractional instance (Double), whereas quot used them with the default Integral instance.

就是说,你的函数不会丢弃最后一位数字。如果您只想将 12345 转换为 1234 ,则可以简化 dropLastDigit

That being said, your function doesn't "drop" the last digit. If you just want to transform 12345 to 1234, you can simplify dropLastDigit to

dropLastDigit x = x `div` 10

但是,如果您想将 12345 转换为 12340

If you, however, want to transform 12345 to 12340, you just have to multiply by ten afterwards:

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

这篇关于Haskell中数字转换的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆