0

我正在使用 Haskell 中的免费 monad,但我一直在定义提升 Free monad 中的函子构造函数的函数。

我将 AppF 函子作为几个函子的总和,每个函子代表一个效果。这些函子之一是 DbTrF,代表 db 交易效果。

所以我的 AppF 是这样定义的:

data AppF a = 
  DbTr (DbTrF a)
  | ... functors for the other types of effects
  deriving (Functor)

我的 DbTrF 定义如下:

data Op i r =
  Get i
  | Insert i r
  | Delete i
  | Update i (r -> r)

data DbTrF a =
  UserTb (Op UserId UserData) (Maybe UserData -> a)
  | SessionTb (Op SessionId SessionData) (Maybe SessionData -> a)
  | ... here is the code for other tables
  deriving(Functor)

那么我想要一个交易功能

transact :: Table i r t-> Op i r -> AppM (Maybe r)

...我想这样使用:

transactExample = transact UserTb (Get someUserId)

为此,我想介绍 Table 类型作为接受操作并返回 DbTrF 值的函数:

newtype Table i r a = Table {tbId :: Op i r -> (Maybe r -> a) -> DbTrF a}

我的尝试是这样的:

transact (Table tb) op = liftF (DbTr (tb op ???))

但我不确定该放什么而不是问号。

这是一个很好的方向还是我做错了?

谢谢!

4

1 回答 1

2

让我们尝试逐步实例化函数的主体,跟踪剩余孔中的预期类型:

transact :: Table i r a -> Op i r -> AppM (Maybe r)
transact (Table tb) op
  = ??? :: AppM (Maybe r)
  = liftF (??? :: AppF (Maybe r))
  = liftF (DbTr (??? :: DbTrF (Maybe r)))
  = liftF (DbTr (tb op (??? :: Maybe r -> Maybe r))

但我们也有,从 , 的Table tb类型tb :: Op i r -> (Maybe r -> a) -> DbTrF a。因此a ~ Maybe r,我们可以直接使用上面的孔来解决id,在类型上稍作改动transact

transact :: Table i r (Maybe r) -> Op i r -> AppM (Maybe r)
transact (Table tb) op = liftF (DbTr (tb op id))
于 2017-03-30T19:43:12.573 回答