我創建了一個newtype
別名IP
類型從Data.IP
:爲什麼這種新類型沒有被賦予正確的Read實例?
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module IPAddress (IPAddress) where
import Data.IP (IP)
import Database.PostgreSQL.Simple.ToField
newtype IPAddress = IPAddress IP
deriving (Read, Show)
instance ToField IPAddress where
toField ip = toField $ show ip
(我想讓它的ToField
一個實例,而無需創建一個孤兒實例。)
新的類型似乎並不儘管如此,應該支持Read
。在這種GHCI成績單,你可以看到,給定的字符串可以解釋爲IP
但不是作爲一個IPAddress
:
*Main IPAddress> :m + Data.IP
*Main IPAddress Data.IP> read "1.2.3.4" :: IP
1.2.3.4
*Main IPAddress Data.IP> read "1.2.3.4" :: IPAddress
IPAddress *** Exception: Prelude.read: no parse
的行爲是一樣的,不管我是否有GeneralizedNewtypeDeriving上。爲什麼實例的IPAddress
與IP
的實例不同?
也給它一個Show實例,並查看它打印的內容。它會以相同的方式讀取。 – amalloy
如果我理解正確,那麼由'derived Read'生成的實例將以與IPAddress'爲'data'類型的方式完全相同的方式工作。 – pyon
@amalloy我將IsString添加到派生類列表中,然後我就能夠通過「1.2.3.4」:: IPAddress創建一個IPAddress。在這個值上調用'show'會給出''IPAddress 1.2.3.4「',實際上'讀取'IPAddress 1.2.3.4」:: IPAddress'就是我想要的。我想你應該把你的評論變成一個答案!不過,我很想解釋爲什麼我必須用'IPAddress'預先給出值。 – bdesham