Haskell 光束代码仅在一个模块中有效
Haskell Beam code only works in one module
我在这样的 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
但我无法像
那样在 Schema
模块之外使用它
(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 文档本身就有这样的用法(代码嵌入在文档中)。参见 https://tathougies.github.io/beam/user-guide/manipulation/insert/ where CustomerId
is defined at https://github.com/tathougies/beam/blob/d87120b58373df53f075d92ce12037a98ca709ab/beam-sqlite/examples/Chinook/Schema.hs#L119
这是一种有点不直观的情况,会在任何使用附加类型的地方发生,而不是特定于 Beam。
因为 DatasouceId
是附加类型 PrimaryKey
的构造函数,您需要导出和导入该类型,就像处理普通的非附加类型一样。这有点不直观,因为 PrimaryKey
最初并未在您的模块中定义。但从某种意义上说,它是:您正在定义该类型的实例,因此您也可以导出它。我想这一定是这背后有争议的逻辑。
像这样从您的 Schema
模块中导出:
module Schema( ..., B.PrimaryKey(..), ... ) where
像这样在任何需要的地方导入:
import Schema(PrimaryKey(..))
我在这样的 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
但我无法像
那样在Schema
模块之外使用它
(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 文档本身就有这样的用法(代码嵌入在文档中)。参见 https://tathougies.github.io/beam/user-guide/manipulation/insert/ where CustomerId
is defined at https://github.com/tathougies/beam/blob/d87120b58373df53f075d92ce12037a98ca709ab/beam-sqlite/examples/Chinook/Schema.hs#L119
这是一种有点不直观的情况,会在任何使用附加类型的地方发生,而不是特定于 Beam。
因为 DatasouceId
是附加类型 PrimaryKey
的构造函数,您需要导出和导入该类型,就像处理普通的非附加类型一样。这有点不直观,因为 PrimaryKey
最初并未在您的模块中定义。但从某种意义上说,它是:您正在定义该类型的实例,因此您也可以导出它。我想这一定是这背后有争议的逻辑。
像这样从您的 Schema
模块中导出:
module Schema( ..., B.PrimaryKey(..), ... ) where
像这样在任何需要的地方导入:
import Schema(PrimaryKey(..))