Haskell eDSL-执行只能在序列中使用一次的操作
我正在开发以下eDSL:Haskell eDSL-执行只能在序列中使用一次的操作,haskell,dsl,free-monad,Haskell,Dsl,Free Monad,我正在开发以下eDSL: import Control.Monad.Free type CommandHandler = PersistedCommand -> Maybe AggregateSnapshot -> CommandDirective data CommandDirective = Reject RejectionReason | SkipBecauseAlreadyProcessed
import Control.Monad.Free
type CommandHandler
= PersistedCommand -> Maybe AggregateSnapshot -> CommandDirective
data CommandDirective = Reject RejectionReason
| SkipBecauseAlreadyProcessed
| Transact (CommandTransaction ())
type RejectionReason = String
data Action a = PersistEvent Event a
| UpdateSnapshot AggregateSnapshot a
| GetCurrentTime (UTCTime -> a )
| GetNewEventId (EventId -> a) deriving (Functor)
type CommandTransaction a = Free Action a
persistEvent :: Event -> CommandTransaction ()
persistEvent event = Free . PersistEvent event $ Pure ()
updateSnapshot :: AggregateSnapshot -> CommandTransaction ()
updateSnapshot aggregateSnapshot
= Free . UpdateSnapshot aggregateSnapshot $ Pure ()
getNewEventID :: CommandTransaction EventId
getNewEventID = Free $ GetNewEventId Pure
getCurrentTime :: CommandTransaction UTCTime
getCurrentTime = Free $ GetCurrentTime Pure
我希望UpdateSnapshot在一个序列中只使用一次,而不是像现在这样使用两次。我可以用幻影类型来做,然后UpdateSnapshot将成为动作链的最后一个元素。但它在语义上有点错误,它不适用于两个性质相同的动作
e、 g:2上次更新Napshot应无效:
do
now <- getCurrentTime
eventId <- getNewEventID
persistEvent $ WorkspaceCreated
{ eventId = eventId
, createdOn = now
, workspaceId = workspaceId }
updateSnapshot $ AggregateSnapshot
{ lastOffsetConsumed = 0
, commandsProcessed = Set.fromList [commandId]
, state = AggregateState { aggregateId = workspaceId } }
updateSnapshot $ AggregateSnapshot
{ lastOffsetConsumed = 0
, commandsProcessed = Set.fromList [commandId]
, state = AggregateState { aggregateId = workspaceId } }
do
现在,你说“没有我现在做的两次”是什么意思?你在哪里使用UpdateSnapshot
?我举了一个dsl的例子来说明我使用两次UpdateSnapshot是什么意思,从操作
中取出UpdateSnapshot
,并使其成为一个FreeT
,你可以用来包含(截肢的)数据CommandTransaction
?大多数函数(persistEvent
,getNewEventID
等)将返回UpdateSnapshotT CommandTransaction a
,但updateSnapshot
将只返回CommandTransaction
。我还没试过,所以这可能是个愚蠢的想法……这是个愚蠢的想法。不要对自己太苛刻:-)