gpt4 book ai didi

haskell - 第 6 章,练习 7,Haskell 从第一原则开始

转载 作者:行者123 更新时间:2023-12-01 11:12:44 27 4
gpt4 key购买 nike

对于下面的代码:

module Main where

data EitherOr a b = Hello a | Goodbye b deriving Show

instance (Eq a, Eq b) => Eq (EitherOr a b) where
(==) (Hello x) (Hello x') = x == x'
(==) (Goodbye x) (Goodbye x') = x == x'
(==) _ _ = False

main :: IO ()
main = do
print (Hello 2 == Hello 2)
-- print (Hello 3 == Hello 2)
-- print (Goodbye 3 == Goodbye 3)
-- print (Goodbye 4 == Goodbye 3)
-- print (Hello 3 == Goodbye 3)

在runhaskell下执行,即在ghc下,出现如下错误:

    • Ambiguous type variable ‘b0’ arising from a use of ‘==’
prevents the constraint ‘(Eq b0)’ from being solved.
Probable fix: use a type annotation to specify what ‘b0’ should be.
These potential instances exist:
instance Eq Ordering -- Defined in ‘GHC.Classes’
instance Eq Integer
-- Defined in ‘integer-gmp-1.0.2.0:GHC.Integer.Type’
instance (Eq a, Eq b) => Eq (EitherOr a b)
-- Defined at /tmp/runghcXXXX61964-0.hs:5:10. <-- This is because I am using org-mode source blocks
...plus 23 others
...plus 11 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In the first argument of ‘print’, namely ‘(Hello 2 == Hello 2)’
In a stmt of a 'do' block: print (Hello 2 == Hello 2)
In the expression: do print (Hello 2 == Hello 2)
|
12 | print (Hello 2 == Hello 2)
| ^^^^^^^^^^^^^^^^^^

我想我可以通过这样做给编译器一个类型提示

print ((Hello (2 :: Int)) == (Hello (2 :: Int)))

或类似的东西,但这似乎还不够。我看到 a 和 b 是多态的,但我认为在 main 中使用 == 可能足以帮助编译器推断类型。

接下来,我在 ghci 中加载了数据类型和类型类实例,并对类型进行了一些探索,例如发现

λ> :t Hello (2 :: Int)
Hello (2 :: Int) :: EitherOr Int b

正如预期的那样。再次在 ghci 中,我进行了更多探索,发现正在使用默认类型

λ> :t(你好 2 == 你好 2)

<interactive>:1:2: warning: [-Wtype-defaults]
• Defaulting the following constraints to type ‘Integer’
(Eq a0) arising from a use of ‘==’ at <interactive>:1:2-19
(Num a0) arising from the literal ‘2’ at <interactive>:1:8
• In the expression: (Hello 2 == Hello 2)

<interactive>:1:2: warning: [-Wtype-defaults]
• Defaulting the following constraint to type ‘()’
Eq b0 arising from a use of ‘==’
• In the expression: (Hello 2 == Hello 2)
(Hello 2 == Hello 2) :: Bool

这当然是我想要的。

然后我实际执行了 ghci 中的代码并通过一些默认设置得到了正确的答案

λ> Hello 2 == Hello 2

<interactive>:27:1: warning: [-Wtype-defaults]
• Defaulting the following constraints to type ‘Integer’
(Eq a0) arising from a use of ‘==’ at <interactive>:27:1-18
(Num a0) arising from the literal ‘2’ at <interactive>:27:7
• In the expression: Hello 2 == Hello 2
In an equation for ‘it’: it = Hello 2 == Hello 2

<interactive>:27:1: warning: [-Wtype-defaults]
• Defaulting the following constraint to type ‘()’
Eq b0 arising from a use of ‘==’
• In the expression: Hello 2 == Hello 2
In an equation for ‘it’: it = Hello 2 == Hello 2

<interactive>:27:1: warning: [-Wtype-defaults]
• Defaulting the following constraints to type ‘Integer’
(Eq a0) arising from a use of ‘==’ at <interactive>:27:1-18
(Num a0) arising from the literal ‘2’ at <interactive>:27:7
• In the expression: Hello 2 == Hello 2
In an equation for ‘it’: it = Hello 2 == Hello 2

<interactive>:27:1: warning: [-Wtype-defaults]
• Defaulting the following constraint to type ‘()’
Eq b0 arising from a use of ‘==’
• In the expression: Hello 2 == Hello 2
In an equation for ‘it’: it = Hello 2 == Hello 2
True

但是在 runhaskell 下执行的相同代码,即在 ghc 编译下,失败并出现我首先给出的错误。我需要在这里学习什么?

最佳答案

GHCi 中的类型默认规则与编译 GHC 等程序时使用的规则不同。当类型不明确时,您应该给出明确的签名,例如:

print (Hello 2 == (Hello 2 :: EitherOr Integer ())

在实践中,这并不经常需要,因为程序的其他部分隐含了类型。像上面这样的玩具和教育片段没有太多可以为类型检查器添加信息的上下文。

关于haskell - 第 6 章,练习 7,Haskell 从第一原则开始,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57948829/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com