【发布时间】:2017-04-03 10:23:11
【问题描述】:
我从Data.IP 创建了IP 类型的newtype 别名:
{-# 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 的Read 实例与IP 的实例不同?
【问题讨论】:
-
也给它一个 Show 实例,看看它打印的内容。它会以相同的方式读取。
-
如果我理解正确,
deriving Read生成的实例的工作方式与IPAddress是data类型完全相同 -
@amalloy 我将
IsString添加到派生类列表中,然后我能够通过"1.2.3.4" :: IPAddress创建一个IPAddress。在这个值上调用show会得到"IPAddress 1.2.3.4",实际上read "IPAddress 1.2.3.4" :: IPAddress可以满足我的要求。我想你应该把你的评论变成答案!不过,我想解释一下为什么我必须在值前面加上IPAddress。