所以在一個檔案中我有
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),這就是我想要的。
這種差異的原因是什么,我該如何解決?
uj5u.com熱心網友回復:
您的定義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實體。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/440933.html
