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) 的定义只要求 abShow 个实例,而不是 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 实例。