Haskell 类的ghci意外行为实例
我一直在浏览Bryan O'Sullivan及其同事的“真实世界Haskell”,在Windows下遇到了我称之为GHCi 7.8.3版的意外“松弛”。 I“:加载”以下内容-Haskell 类的ghci意外行为实例,haskell,instance,gchi,Haskell,Instance,Gchi,我一直在浏览Bryan O'Sullivan及其同事的“真实世界Haskell”,在Windows下遇到了我称之为GHCi 7.8.3版的意外“松弛”。 I“:加载”以下内容- module JSONModule where data JValue = JNumber Double | JBool Bool deriving ( Show, Eq, Ord ) class JSON a where toJValue :: a ->
module JSONModule where
data JValue = JNumber Double
| JBool Bool
deriving ( Show, Eq, Ord )
class JSON a where
toJValue :: a -> JValue
fromJValue :: JValue -> Either String a
fromJBool (JBool b) = Right b
fromJBool _ = Left "not a JSON boolean"
instance JSON Double where
toJValue = JNumber
fromJValue = doubleToJValue id
instance JSON Bool where
toJValue = JBool
fromJValue = fromJBool
doubleToJValue :: (Double -> a) -> JValue -> Either String a
doubleToJValue f (JNumber v) = Right (f v)
doubleToJValue _ _ = Left "not a JSON number"
然后,在ghci中:
*JSONModule> :r
[1 of 1] Compiling JSONModule ( JSONModule.hs, interpreted )
Ok, modules loaded: JSONModule.
*JSONModule> toJValue False
JBool False
*JSONModule> fromJValue it
Left "not a JSON number"
虽然这是真的,但这并不是人们所期望的。我认为ghci应该告诉我放风筝,因为fromJValue有两个例子。
的确,如果我具体说明的话
fromJValue it :: Either String Bool
我是对的。问题似乎是双重价值。消除JSON双实例,并向JValue添加一个JChar Char构造函数和一个JSON Char的对应实例,我从ghci获得了预期的“不明确”响应。
所以我认为有一个bug。
评论?感谢……了解真实情况:
[1 of 1] Compiling JSONModule ( test.hs, interpreted )
Ok, modules loaded: JSONModule.
>:set -Wall
>:t fromJValue (toJValue False)
fromJValue (toJValue False) :: JSON a => Either String a
> fromJValue (toJValue False)
<interactive>:6:2: Warning:
Defaulting the following constraint(s) to type `Double'
(JSON a0) arising from a use of `it' at <interactive>:6:2-28
(Show a0) arising from a use of `print' at <interactive>:6:2-28
In the first argument of `print', namely `it'
In a stmt of an interactive GHCi command: print it
Left "not a JSON number"
[1/1]编译JSONModule(test.hs,解释)
好的,已加载模块:JSONModule。
>:设置-墙
>:t fromJValue(toJValue False)
fromJValue(toJValue False)::JSON a=>字符串a
>fromJValue(toJValue False)
:6:2:警告:
将以下约束默认为键入'Double'
(JSON a0)源于在6:2-28使用“it”
(显示a0)因在6:2-28使用“打印”而产生
在'print'的第一个参数中,即'it'
在交互式GHCi命令的stmt中:打印它
左“不是JSON编号”
如您所见,ghc将不明确的类型变量默认为Double。当没有Double的实例时,它会给出不明确的类型错误,这是因为默认行为仅将默认约束设置为Integer或Double,因为这些是最有用(或常见)的情况 这不是错误,而是错误的结果,默认情况下在GHCi提示符下启用,但不在文件中启用 大约,当一个类型在其他方面不明确并且具有正确形式的类约束时,具有此扩展的GHC将尝试将其默认为符合
()、Integer、Double
的第一个类型
如果没有扩展的DefaultRules扩展,例如默认情况下在模块文件中,默认仍然可以发生,但是要求更严格(必须至少涉及一个数值类,并且不尝试使用()
),并且只适用于一组固定的类,而不适用于您自己定义的任何类