在ghci中显示对类型或多或少的挑剔



如果我启动ghci并输入一个简单的算术表达式,我通常会得到预期的结果。

GHCi λ: 6 * 7
42

然而,我正在遵循一个教程中的例子,这是一个阴谋项目的一部分。如果我在项目中启动ghci,例如cabal repl Example并尝试相同的表达式,我会得到以下结果:

GHCi λ: 6 * 7
<interactive>:4:1: error: [-Wtype-defaults, -Werror=type-defaults]
• Defaulting the following constraints to type ‘Integer’
(Show a0) arising from a use of ‘print’ at <interactive>:4:1-5
(Num a0) arising from a use of ‘it’ at <interactive>:4:1-5
• In a stmt of an interactive GHCi command: print it

我必须指定表达式的类型:

GHCi λ: 6 * 7 :: Int
42

我想了解是什么可能使'show'在教程的项目中更挑剔,如果有一些方法可以回到'明智的'默认值的便利。

你的问题与Haskell如何处理数字字面量有关:有人可能会认为像6这样的数字具有Int(或Integer)类型;但是,如果您询问ghci6的类型,您将得到:

λ> :t 6
6 :: Num p => p

这意味着6(或任何数字字面量)实际上是一个泛型p的值,前提是p有一个Num实例。通常,由于类型注释,编译器能够自动理解您实际需要的数字类型:

plus2 :: Int -> Int 
plus2 x = x + 2
--            ^
--            since x has type Int (and Int has a Num instance)
--            2 is considered an Int as well

当编译器不能理解你需要的类型字面量的具体类型时,它将默认为Integer,例如,如果你写:

print 2
-- print :: Show a => a -> IO ()
-- 2 :: Num p => p

这里print (2 :: Int)print (2 :: Integer)都是正确的,所以编译器默认为2 :: Integer。这种默认行为可能并不总是好的(特别是因为Integers比Ints效率低),所以每次发生这种情况时,都会有一个GHC编译标志警告你。

您的项目的.cabal必须启用-Wtype-defaults-Werror标志。如果你删除了-Werror,你仍然会看到这个默认行为的警告,但至少你的代码会执行;您也可以删除-Wtype-defaults来禁用警告。如果您在.cabal文件中没有看到-Wtype-default,这是因为它也可以通过指定以下标志之一来启用:-Wall,-Weverithing

TL;DR您应该从项目的.cabal文件中删除这些编译标志之一:

  • -Wtype-defaults(或-Wall/-Weverithing)
  • -Werror

相关内容

  • 没有找到相关文章

最新更新