使用runhaskell运行含nullIV的代码报错,GHCi中却正常的问题
这个问题其实是Haskell类型推断在脚本运行和GHCi交互模式下的行为差异搞的鬼,我来给你捋清楚:
为什么会出现这个差异?
先看nullIV的类型签名:它是BlockCipher c => IV c,这意味着它需要一个具体的BlockCipher实例类型来确定c到底是什么。
- 在GHCi里,默认开启了
ExtendedDefaultRules扩展,这个扩展会帮你自动选一个合理的默认类型(比如常用的AES加密算法对应的类型),所以你定义iv0的时候不会有类型推断问题。 - 但用
runhaskell跑脚本时,默认没开这个扩展,编译器找不到c的具体类型,就会抛出那个“No instance for (BlockCipher c0)”的错误。
两种解决办法
1. 显式指定类型(推荐)
直接给iv0指定一个具体的BlockCipher对应的IV类型,比如用AES的话,需要先导入对应的模块:
import Crypto.Cipher.Types import Crypto.Cipher.AES main::IO() main = do let iv0 = nullIV :: IV AES print ""
这样编译器一眼就知道要使用AES的BlockCipher实例,不会再纠结类型问题。
2. 启用自动默认类型扩展
在脚本最开头加上扩展声明,让编译器和GHCi一样自动推断默认类型:
{-# LANGUAGE ExtendedDefaultRules #-} import Crypto.Cipher.Types main::IO() main = do let iv0 = nullIV print ""
不过这种方式依赖编译器的默认类型选择,不同环境下可能有差异,还是显式指定类型更稳妥。
内容的提问来源于stack exchange,提问作者Mahesh Uligade
相关产品推荐
相关产品推荐

