Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell eDSL-执行只能在序列中使用一次的操作_Haskell_Dsl_Free Monad - Fatal编程技术网

Haskell 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

我正在开发以下eDSL:

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
。我还没试过,所以这可能是个愚蠢的想法……这是个愚蠢的想法。不要对自己太苛刻:-)