The*_*ave 0 haskell types show
所以在一个文件中我有
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
Run Code Online (Sandbox Code Playgroud)
在另一个名为 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
Run Code Online (Sandbox Code Playgroud)
当我在 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
Run Code Online (Sandbox Code Playgroud)
然后show (Branch "+" (Leaf 1) (Leaf 2))将按预期工作:myshow "+"将使用MyShow String实例,而不是Show a => MyShow a实例。