gpt4 book ai didi

haskell - 为什么 Haskell 中的这种类型注释是必要的?

转载 作者:行者123 更新时间:2023-12-04 07:55:00 24 4
gpt4 key购买 nike

我正在研究 GHC 中的函数重载有多强大。我编写了以下代码:

class F_third_arg a where
run_f :: (Integer, a) -> Integer

instance F_third_arg Integer where
run_f (_, x) = x

instance F_third_arg String where
run_f (x, _) = x

my_fun :: (F_third_arg a) => Integer -> (a -> Integer)
my_fun x = \a -> run_f(x, a)

main :: IO ()
main = putStrLn $ show( ((my_fun::Integer->(Integer->Integer)) 5) $ 6)

(是的,我需要 -XTypeSynonymInstances -XFlexibleInstances)而且我很惊讶编译器需要在调用 my_fun 附近的类型注释。 .它适用于两个数字——推断这个注释有什么问题?开启这两个扩展的重载规则是什么?

最佳答案

您的代码的问题是数字文字本身已经重载。所以文字 6有类型 Num a => a , 而 my_fun 5有类型 F_third_arg b => b -> Integer .所以在类型推断时,它统一了这两个类型变量。但由于对它们没有其他要求,GHC 在这里找不到要使用的具体类型,并给出适当的错误消息:

测试.hs:16:26:
没有因使用“my_fun”而产生 (F_third_arg a0) 的实例
类型变量“a0”不明确
可能的修复:添加修复这些类型变量的类型签名
注意:有几种可能的情况:
instance F_third_arg 字符串——在 test.hs:9:10 定义
instance F_third_arg 整数——在 test.hs:6:10 定义
在表达式中:(my_fun 5)
在`show'的第一个参数中,即`((my_fun 5) $ 6)'
在`($)'的第二个参数中,即`show ((my_fun 5) $6)'

测试.hs:16:38:
(Num a0) 没有由文字“6”产生的实例
类型变量“a0”不明确
可能的修复:添加修复这些类型变量的类型签名
注意:有几种可能的情况:
instance Num Double -- 在 `GHC.Float' 中定义
instance Num Float -- 在 `GHC.Float' 中定义
instance Integral a => Num (GHC.Real.Ratio a)
-- 在“GHC.Real”中定义
...加上另外三个
在‘($)’的第二个参数中,即‘6’
在`show'的第一个参数中,即`((my_fun 5) $ 6)'
在`($)'的第二个参数中,即`show ((my_fun 5) $6)'

人们可能期望编译器注意到 Integer是满足这两个要求的唯一类型,但是这种启发式方法会使您的代码相对脆弱,即它会因为您添加一个新实例而中断(例如 F_third_arg Double )。因此编译器会拒绝该代码并要求您明确说明所讨论的类型。

您找到了一种解决方法,但 @leftroundabouts 建议使用 6::Integer好一点。

关于haskell - 为什么 Haskell 中的这种类型注释是必要的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17522987/

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