Haskell Beam代码仅在一个模块中工作
我在Haskell Beam代码仅在一个模块中工作,haskell,haskell-beam,Haskell,Haskell Beam,我在Schema模块中定义了DatasourceId,如下所示 import qualified Database.Beam as B data DatasourceT f = Datasource { _datasourceId :: B.C f Text , _datasourceName :: B.C f Text } deriving (Generic, B.Beamable) instance B.Table DatasourceT where data Pri
Schema
模块中定义了DatasourceId
,如下所示
import qualified Database.Beam as B
data DatasourceT f = Datasource
{ _datasourceId :: B.C f Text
, _datasourceName :: B.C f Text
} deriving (Generic, B.Beamable)
instance B.Table DatasourceT where
data PrimaryKey DatasourceT f = DatasourceId (B.C f Text) deriving (Generic, B.Beamable)
primaryKey = DatasourceId . _datasourceId
type DatasourceId = B.PrimaryKey DatasourceT Identity
但我无法在模式
模块之外使用它,如中所示
(B.val_ $ DatasourceId $ _datasourceId d)
因为编译器会抱怨
> • Data constructor not in scope:
> DatasourceId :: t0 -> B.PrimaryKey DatasourceT Identity
> • Perhaps you meant 'Datasource' (imported from Schema)
> |
> 229 | (B.val_ $ DatasourceId $ _datasourceId d)
即使我有
import Schema (ControlAccessDb(..), Datasource, DatasourceId, DatasourceT(..))
那么,有什么建议可以防止代码注定要被集成到一个模块中呢?这可能是一种类型家族的怪癖吗?
问题似乎在于
instance B.Table DatasourceT where
data PrimaryKey DatasourceT f = DatasourceId (B.C f Text) deriving (Generic, B.Beamable)
primaryKey = DatasourceId . _datasourceId
其中实例化内部仅为定义模块所知
请注意,Beam文档本身有这样的用法(文档中嵌入的代码)。请参见中定义的
CustomerId
,这是一种不直观的情况,发生在使用附加类型的任何地方,而不是特定于梁
由于DatasouceId
是附加类型PrimaryKey
的构造函数,因此需要导出和导入该类型,就像导出普通的非附加类型一样。这有点不直观,因为PrimaryKey
最初不是在模块中定义的。但从某种意义上说,它是:您正在定义该类型的实例,所以您也可以导出它。我想这一定是有争议的逻辑
从模式中导出如下内容:
module Schema( ..., B.PrimaryKey(..), ... ) where
import Schema(PrimaryKey(..))
按如下方式在需要时导入:
module Schema( ..., B.PrimaryKey(..), ... ) where
import Schema(PrimaryKey(..))
导出应该是合格的,因此我认为您的意思是模块模式(…,B.PrimaryKey(…),…),其中
是的,您是对的:在您的情况下,由于Database.Beam.Schema
是作为合格导入的,因此您也应该参考PrimaryKey
。我已经更新了答案。如果我有几个类型同义词,例如typed2id=B.PrimaryKey D2T Identity
?“work”以什么方式工作?Table
是一个类,而PrimaryKey
是一个附加类型。这大致意味着“每个表
的实例都必须附加一些主键
的定义”。你正在定义两者。您正在将PrimaryKey
的实例定义为data
类型,其中一个构造函数名为DatasourceId
。