我创建了一个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