Haskell类型混淆问题:预期类型Int与实际类型Integer不匹配
斐波那契计算黄金分割比的类型不匹配问题
我尝试用斐波那契数列计算黄金分割比,首先定义了生成下一对斐波那契数的fibstep函数:
fibstep :: (Num a) => (a,a) -> (a,a) fibstep (u,v) = (v,u + v)
随后我尝试用lambda函数实现计算黄金分割比的golden_ratio函数:
golden_ratio :: (Fractional a) => Integer -> [a] golden_ratio n = map (\(x,y) -> x/y) (take n (iterate fibstep (0,1)))
但运行时出现如下错误:
Recursions.hs:68:44: error: • Couldn't match expected type ‘Int’ with actual type ‘Integer’ • In the first argument of ‘take’, namely ‘n’ In the second argument of ‘map’, namely ‘(take n (iterate fibstep (0, 1)))’ In the expression: map (\ (x, y) -> x / y) (take n (iterate fibstep (0, 1))) | 68 | golden_ratio n = map (\(x,y) -> x/y) (take n (iterate fibstep (0,1))) | ^ Failed, no modules loaded
当我将参数类型从Integer改为Int后,函数可以正常运行:
golden_ratio :: (Fractional a) => Int -> [a] golden_ratio n = map (\(x,y) -> x/y) (take n (iterate fibstep (0,1)))
原因解释
Haskell标准库中take函数的类型签名为take :: Int -> [b] -> [b],它要求第一个参数必须是Int类型(有界整数,对应机器原生整数范围),而非Integer类型(无界大整数,可表示任意大小的整数)。
你最初的代码里,golden_ratio的参数n被声明为Integer,但传给take时,take期望的是Int,类型不匹配导致编译器抛出错误。把参数类型改为Int后,类型完全匹配,函数就能正常执行了。
如果确实需要保留Integer类型的参数,可通过fromIntegral做类型转换,将Integer转为Int:
golden_ratio :: (Fractional a) => Integer -> [a] golden_ratio n = map (\(x,y) -> x/y) (take (fromIntegral n) (iterate fibstep (0,1)))
内容的提问来源于stack exchange,提问作者jack lee
相关产品推荐
相关产品推荐

