寻找无需引号的Read替代:Haskell中Text转多类型的类型类选择
问题描述
我的应用需要频繁将Text类型转换为各类数据类型(包括Text本身),偶尔也涉及String、ByteString等其他字符串类型的转换。我发现Readable.fromText可满足Integer和Text类型的转换需求,但它暂不支持UTCTime类型(不过我可自行实现对应实例)。
原本我以为Readable.fromText是Text版本的Text.Read.readEither,实际二者存在差异:readEither处理Text时要求输入带引号,处理Integer则无需引号——这是因show输出的字符串带引号,read为保持一致性要求引号。但我需要的是将字符串读取为字符串时等价于id函数的类型类,Readable符合该行为,但命名易产生误解,因其与[Char]上的read行为并不完全一致。
我想了解:是否有其他具备该行为的类型类?或是直接扩展Readable(如新类型或提交PR)更合适?
可行方案
1. 现有替代类型类
Parseable(parseable包):该类型类专为直接解析字符串为对应类型设计,解析Text时无需引号,与你需求的行为完全匹配,同时支持Text、String、ByteString等多种字符串类型的转换。- 单向转换类(如
FromText/ToText):不少库会提供这类单向转换的类型类,你可以基于现有库扩展实例,也可以自行定义一个更贴合业务的类型类(比如FromStringLike),统一处理所有字符串类型的解析逻辑。
2. 扩展Readable的方案
- 自定义新类型包装:若不想改动原库,可通过新类型(如
newtype UnquotedText = UnquotedText Text)为UTCTime或其他目标类型实现Readable实例,避免污染全局实例环境。 - 提交上游PR:如果
UTCTime的Readable实例属于通用需求,直接给Readable库提交PR添加实例是更长久的解决方案,同时可以提议补充文档说明或添加别名,消除命名带来的误解。
3. 自定义类型类
如果现有方案都不符合预期,完全可以自己定义一个贴合需求的类型类,示例如下:
class StringParse a where parseText :: Text -> Either String a parseString :: String -> Either String a parseByteString :: ByteString -> Either String a -- 提供默认实现减少重复代码 parseString = parseText . pack parseByteString = parseText . decodeUtf8
这种方式可以完全按照你的业务逻辑定制,命名也更清晰直观。
内容的提问来源于stack exchange,提问作者Clinton
相关产品推荐
相关产品推荐

