在GHCI或多或少挑剔的类型中展示

发布于 2025-02-08 06:26:33 字数 706 浏览 1 评论 0 原文

如果我启动GHCI并输入一个简单的算术表达式,我通常不会在没有大惊小怪的情况下获得预期的结果

GHCi λ: 6 * 7
42

,但是我在教程中遵循的示例是Cabal Project的一部分。如果我在项目中启动GHCI,例如 cabal reploce示例,请尝试相同的表达式,我得到以下内容:

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

我想了解可能制作的“显示” 的内容教程的项目中更挑剔,如果有某种方法可以回到“明智”默认值的便利。

If I fire up ghci and type in a simple arithmetic expression, I usually get the expected result with no fuss

GHCi λ: 6 * 7
42

However, I am following the examples in a tutorial which are part of a cabal project. If I launch ghci within the project, e.g. cabal repl Example and try the same expression I get the following:

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

I am forced to specify the expression's type:

GHCi λ: 6 * 7 :: Int
42

I would like to understand what has likely made 'show' more picky in the tutorial's project, and if there is some way to get back to the convenience of 'sensible' defaults.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

人海汹涌 2025-02-15 06:26:33

您的问题与Haskell如何处理数字文字有关:有人可能会认为 6 具有类型 int (或 integer );但是,如果您向GHCI询问 6 您会得到的类型:

λ> :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 ,for 示例如果您写:

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

此处 print(2 :: int) print(2 :: Integer)是正确的,因此编译器默认为 2 :::::::整数
这种默认行为可能并非总是可以的(尤其是因为 Integer s的效率不如 int s),因此每次发生这种情况时都会警告您。

您的项目的 .cabal 必须已启用 -wtype-defaults -werror 您仍然会看到有关此默认行为的警告,但至少您的代码将执行;您还可以删除 -wtype-defaults 以禁用警告。
如果您在 .cabal 文件中没有看到 -wtype-default ,则可以通过指定此标志之一来启用它:
-weverithing

tl; dr 您应该从项目的 .cabal 文件中删除这些汇编标志之一:

  • -wtype-defaults (或 -wall) / -weverithing
  • -werror

Your issue is related to how Haskell deals with number literals: one might think that a number like 6 has type Int (or Integer); however, if you ask ghci the type of 6 you'll get:

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

What this means is that 6 (or any number literal) is actually a value of a generic type p provided that p has a Num instance. Usually, thanks to type annotations, the compiler is automatically able to understand which numeric type you actually want:

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

When the compiler can not understand what specific type you need for your type literal it will default to Integer, for example if you write:

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

Here both print (2 :: Int), and print (2 :: Integer) are correct so the compiler defaults to 2 :: Integer.
This defaulting behaviour might not always be ok (especially since Integers are less efficient than Ints), so there is a GHC compilation flag that warns you every time this happens.

Your project's .cabal must have enabled the -Wtype-defaults and the -Werror flags. If you remove -Werror you'll still see the warning about this defaulting behaviour but at least your code will execute; you can also remove the -Wtype-defaults to disable the warning.
If you do not see the -Wtype-default in your .cabal file it is because it can also be enabled by specifying one of this flags: -Wall, -Weverithing.

TL;DR you should remove one of these compilation flags from the project's .cabal file:

  • -Wtype-defaults (or -Wall/-Weverithing)
  • -Werror
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文