我在Haskell中玩自由monads,我被困在定义在Free monad中提升函子构造函数的函数上。
我将 AppF 函子作为几个函子的总和,每个函子代表一个效果。其中一个函子是 DbTrF,表示数据库事务效应。
所以我的 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 ???))
但我不确定要放什么而不是问号。
这是一个好的方向还是我做错了?
谢谢!
让我们尝试逐步实例化函数的主体,在剩余的孔中跟踪预期的类型:
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))