为含[String]字段的类型派生FromRow遇编译错误求助
Haskell postgresql-simple: [String]的FromField实例问题
编译错误的核心原因是:postgresql-simple没有为原生Haskell列表[String]提供默认的FromField实例。PostgreSQL中的数组类型对应的是库中的PGArray a类型,而非直接的Haskell列表,所以自动派生FromRow时无法匹配类型。
解决方案:快速添加实例保留自动派生
不需要手写完整的FromRow实例,只需为[String]定义一个简单的FromField实例(需要开启FlexibleInstances扩展):
{-# LANGUAGE FlexibleInstances #-} import Database.PostgreSQL.Simple.FromField import Database.PostgreSQL.Simple.Types (PGArray(..)) instance FromField [String] where fromField field dat = fromPGArray <$> fromField field dat
定义完这个实例后,你原来的Reading类型定义可以完全保留,自动派生的FromRow就能正常工作:
data Reading = Reading { id :: UUID , title :: String , authors :: [String] , startDate :: Day , finishDate :: Maybe Day } deriving (Eq, Show, Generic, FromRow)
为什么没有现成实例?
postgresql-simple的设计原则是让Haskell类型与PostgreSQL数据库类型严格对应:PostgreSQL中的text[]类型对应库中的PGArray String,而非原生Haskell列表[String]。这种设计避免了类型歧义,所以原生列表没有默认的FromField实例。
替代方案(不推荐)
如果你不想定义全局实例,也可以把Reading中的authors字段类型改为PGArray String,之后在业务代码中通过fromPGArray转换为[String],但这种方式会增加额外的类型转换成本,不如第一种方案简洁。
内容的提问来源于stack exchange,提问作者Razumov
相关产品推荐
相关产品推荐

