Haskell 显示错误?
Haskell Show bug?
所以在一个文件中我有
import Data.String
import MyShow
data Tree a b = Leaf a | Branch b (Tree a b) (Tree a b)
instance (Show a, Show b) => Show (Tree a b) where
show (Branch n t1 t2) = "(" ++ myshow t1 ++ myshow n ++ myshow t2 ++ ")"
show (Leaf l) = myshow l
newtype MyString = MyString String
instance Show MyString where
show (MyString s) = s
在另一个名为 MyShow.hs 的文件中,我有
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
module MyShow where
class MyShow a where
myshow :: a -> String
instance {-# OVERLAPPING #-} MyShow String where
myshow s = s
instance Show a => MyShow a where
myshow = show
当我在 ghci 中加载第一个文件时,(Branch "+" (Leaf 1) (Leaf 2)
显示 (1"+"2)
,当我尝试 "(" ++ myshow (Leaf 1) ++ myshow "+" ++ myshow (Leaf 2) ++ ")"
时,显示 (1+2)
,这就是我想要的。
出现这种差异的原因是什么?我该如何解决?
您对 Show (Tree a b)
的定义只要求 a
和 b
有 Show
个实例,而不是 MyShow
个实例。因此(我认为我无法准确解释原因),Show a => MyShow a
的实例优先于 MyShow String
,因为类型检查器不知道 a
具有 MyShow
实例是可能的。
如果将约束更改为
instance (MyShow a, MyShow b) => Show (Tree a b) where
然后 show (Branch "+" (Leaf 1) (Leaf 2))
将按预期工作:myshow "+"
将使用 MyShow String
实例,而不是 Show a => MyShow a
实例。
所以在一个文件中我有
import Data.String
import MyShow
data Tree a b = Leaf a | Branch b (Tree a b) (Tree a b)
instance (Show a, Show b) => Show (Tree a b) where
show (Branch n t1 t2) = "(" ++ myshow t1 ++ myshow n ++ myshow t2 ++ ")"
show (Leaf l) = myshow l
newtype MyString = MyString String
instance Show MyString where
show (MyString s) = s
在另一个名为 MyShow.hs 的文件中,我有
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
module MyShow where
class MyShow a where
myshow :: a -> String
instance {-# OVERLAPPING #-} MyShow String where
myshow s = s
instance Show a => MyShow a where
myshow = show
当我在 ghci 中加载第一个文件时,(Branch "+" (Leaf 1) (Leaf 2)
显示 (1"+"2)
,当我尝试 "(" ++ myshow (Leaf 1) ++ myshow "+" ++ myshow (Leaf 2) ++ ")"
时,显示 (1+2)
,这就是我想要的。
出现这种差异的原因是什么?我该如何解决?
您对 Show (Tree a b)
的定义只要求 a
和 b
有 Show
个实例,而不是 MyShow
个实例。因此(我认为我无法准确解释原因),Show a => MyShow a
的实例优先于 MyShow String
,因为类型检查器不知道 a
具有 MyShow
实例是可能的。
如果将约束更改为
instance (MyShow a, MyShow b) => Show (Tree a b) where
然后 show (Branch "+" (Leaf 1) (Leaf 2))
将按预期工作:myshow "+"
将使用 MyShow String
实例,而不是 Show a => MyShow a
实例。