FromRow我的数据不是多态的:

时间:2016-03-28 21:59:09

标签: haskell

我试图为我的数据创建一个不具有多态性的实例:

import Database.PostgreSQL.Simple
import Database.PostgreSQL.Simple.FromRow
data MyData = A | B | C 

instance FromRow MyData where
  fromRow = MyData <$> field -- doesn't compile

但它没有编译。

更新:

我无法编译

instance FromField MyData where
  fromField f mbs = 
    case mbs of
      Just val -> A --????
      Nothing -> returnError ConversionFailed f "error"

这会引发错误Couldn't match expected type ‘Conversion MyData with actual type MyData

如何让它返回Conversion MyData

1 个答案:

答案 0 :(得分:2)

你需要提出

fromRow :: RowParser MyData

你有

field :: FromField a => RowParser a

为任何RowParser实例生成FromField(行的解析器的片段)。

你可以写

fromRow = field

将单字段行解析为MyData。但是,您的MyData类型看起来并不像应该有FromRow个实例。它可能应该(仅)FromField实例。

您当前代码的最大技术问题是您尝试将类型构造函数映射到某些内容上。您只能映射 functions (包括数据构造函数和记录字段访问器)。

对更新的响应

你可能想要

instance FromField MyData where
  fromField f mbs = do
    char <- fromField f mbs
    case char of
      'A' -> pure A
      'B' -> pure B
      'C' -> pure C
      _ -> returnError ConversionFailed f [char]

如果您尝试将包含字符的字段的内容转换为您的类型,则此功能应该有效。如果您正在处理不同类型的字段格式,则可能需要进行调整。

这是使用解析器组合子库的一种非常常见的方法。您应该首先查看库是否为类似类型或类型的组件提供解析器,而不是从头开始为您的类型构建解析器。然后,您可以使用标准FunctorApplicativeMonad操作以及库提供的任何特殊操作来构建解析器。