阅读Learn You a Haskell,我正在研究以下内容:
import System.Random
-- We could make a function that generates a finite stream of numbers and a new generator.
finiteRandoms :: (RandomGen g, Random a) => Int -> g -> ([a], g)
finiteRandoms 0 g = ([], g)
finiteRandoms n g = let (num, gen) = random g
in (take n $ num : randoms gen, gen)
请注意,上述功能不正确,因为它返回“下一个”gen
而不是n
。
Per LYAH,正确的签名是:
finiteRandoms :: (RandomGen g, Random a, Num n) => n -> g -> ([a], g)
。
当我尝试take n $ num
其中n
是Num
类型时,它无法编译:
Could not deduce (n ~ Int)
。
鉴于Num
,如何将其转换为Int
以致电take n
?
答案 0 :(得分:13)
一般来说,无法将Num a => a
转换为Int
。这是因为没有从许多数字类型到整数的规范映射。例如,不可能以1:1的对应关系将复数映射到整数。如果您要将Double
转换为Int
,则可以使用round
,但没有可以为任何数字类型执行此操作的函数。
答案 1 :(得分:10)
如果您想为n
使用多态类型,Data.List
总是genericTake
:
genericTake :: Integral i => i -> [a] -> [a]
由于bhkelir指出的原因,你不会像Num
那样普遍。