【问题标题】:GHC says "digits" needs an Int, when it needs an IntegralGHC 说“数字”需要一个 Int,而它需要一个 Integral
【发布时间】:2015-08-04 20:48:20
【问题描述】:

据我所知,这段代码 sn-p 应该可以毫无问题地编译:

import Data.Digits (digits)
-- |convert integer to arbitrary base with specified charset
-- base/radix is charset string length.
-- eg. convert the integer 255 to hex:
--      intToBaseN 255 "0123456789abcdef" = "ff"
numToBaseN :: Integral n => n -> [Char] -> String
numToBaseN num charlst = map (\i -> charlst !! (fromIntegral i)) lst where
    lst = digits (length charlst) num

但 GHC 抱怨 lst 表达式中的 num 不是 Int。但是digits的类型是

digits :: Integral n => n -> n -> [n]

它不需要Int 作为参数,只需要一个整数,numToBaseN 的类型签名也是如此。

!! 需要一个 Int,这就是它使用 fromIntegral 转换的原因。

这是怎么回事?

如果我将num 替换为(fromIntegral num),它会编译,但是我失去了转换整数(即任意大整数)的能力。

【问题讨论】:

    标签: haskell ghc


    【解决方案1】:

    digits 的两个参数需要具有相同的类型,而 length charlst 的类型为 Int,因此 num 的类型也必须为 Int

    如果我用 (fromIntegral num) 替换 num,它会编译,但是我失去了转换 Integer 的能力

    如果您改为将fromIntegral 应用到length charlst,它会将其转换为num 的任何类型,因此它会按照您想要的方式工作。

    【讨论】:

    • genericLength 也是一个选项,但不太常用可能是因为它需要另一个导入行。
    • @ThomasM.DuBuisson genericLength 的性能通常要差得多(尽管至少存在针对 IntInteger 的重写规则。)
    • @sepp2k 谢谢。我想我很难理解 fromIntegral 从 Integer 转换为 Int 以及反之亦然。再加上 GHC 错误消息使它看起来像最后一个参数是问题,而不是第一个参数(即错误是“num not of right type”而不是“type mismatch between first and second argument to numbers”)。
    猜你喜欢
    • 2020-01-25
    • 1970-01-01
    • 1970-01-01
    • 2021-06-14
    • 2012-11-08
    • 2021-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多