GHC 说 "digits" 需要 Int,而它需要 Integral

GHC says "digits" needs an Int, when it needs an Integral

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

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),它会编译,但随后我将失去转换整数(即任意大整数)的能力。

digits 的两个参数必须具有相同的类型并且 length charlst 具有类型 Int,因此 num 也必须具有类型 Int

It compiles if I replace num with (fromIntegral num), but then I lose the ability to convert an Integer

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