首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >提升数据记录类型

提升数据记录类型
EN

Stack Overflow用户
提问于 2019-05-03 00:06:01
回答 2查看 60关注 0票数 0

假设我们有以下数据类型

代码语言:javascript
复制
data GsdCommand =  CreateWorkspace { commandId :: CommandId , workspaceId ::WorkspaceId , workspaceName :: Text }
             | RenameWorkspace { commandId :: CommandId , workspaceId ::WorkspaceId , workspaceNewName :: Text }

我想要有一个只接受CreateWorkspace的函数:

代码语言:javascript
复制
{-# LANGUAGE DataKinds #-}
handle :: Offset ->
          `CreateWorkspace CommandId WorkspaceId Text  ->
          IO (CommandHandlingResult)

这是我自然而然的做法,但我有以下编译器错误:

代码语言:javascript
复制
Expected a type, but‘ 'CreateWorkspace CommandId WorkspaceId Text’ has kind ‘GsdCommand’
Expected kind ‘CommandId’, but ‘CommandId’ has kind ‘*’
Expected kind ‘WorkspaceId’, but ‘WorkspaceId’ has kind ‘*’
Expected kind ‘Text’, but ‘Text’ has kind ‘*’

这是上下文:

代码语言:javascript
复制
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE NamedFieldPuns #-}
module Eventuria.GSD.Write.CommandConsumer.Handling.HandleGSDCommand (handleGSDCommand) where

import           Eventuria.Libraries.PersistedStreamEngine.Interface.PersistedItem

import           Eventuria.Libraries.CQRS.Write.CommandConsumption.Definitions
import           Eventuria.Libraries.CQRS.Write.CommandConsumption.CommandHandlingResult


import           Eventuria.GSD.Write.Model.WriteModel
import           Eventuria.GSD.Write.Model.Commands.Command
import           Eventuria.GSD.Write.CommandConsumer.Handling.CommandPredicates
import qualified Eventuria.GSD.Write.CommandConsumer.Handling.Commands.CreateWorkspace          as CreateWorkspace
import qualified Eventuria.GSD.Write.CommandConsumer.Handling.Commands.RenameWorkspace          as RenameWorkspace
import qualified Eventuria.GSD.Write.CommandConsumer.Handling.Commands.SetGoal                  as SetGoal
import qualified Eventuria.GSD.Write.CommandConsumer.Handling.Commands.RefineGoalDescription    as RefineGoalDescription
import qualified Eventuria.GSD.Write.CommandConsumer.Handling.Commands.StartWorkingOnGoal       as StartWorkingOnGoal
import qualified Eventuria.GSD.Write.CommandConsumer.Handling.Commands.PauseWorkingOnGoal       as PauseWorkingOnGoal
import qualified Eventuria.GSD.Write.CommandConsumer.Handling.Commands.NotifyGoalAccomplishment as NotifyGoalAccomplishment
import qualified Eventuria.GSD.Write.CommandConsumer.Handling.Commands.GiveUpOnGoal             as GiveUpOnGoal
import qualified Eventuria.GSD.Write.CommandConsumer.Handling.Commands.ActionizeOnGoal          as ActionizeOnGoal
import qualified Eventuria.GSD.Write.CommandConsumer.Handling.Commands.NotifyActionCompleted    as NotifyActionCompleted

type GSDCommandHandler  = Maybe GsdWriteModel ->
                         (Persisted GsdCommand) ->
                         IO (CommandHandlingResult)

handleGSDCommand :: HandleCommand GsdWriteModel
handleGSDCommand writeModelMaybe
               PersistedItem {offset , item = command }
  | (isFirstCommand offset) && (not . isCreateWorkspaceCommand) command = return $ CommandRejected "CreateWorkspace should be the first command"
  | otherwise =   gsdCommandHandler writeModelMaybe PersistedItem {offset , item = (fromCommand command) }

gsdCommandHandler :: GSDCommandHandler
gsdCommandHandler
        writeModelMaybe
        PersistedItem {offset , item = gsdCommand } =
  case (writeModelMaybe, gsdCommand) of
     (Nothing        ,CreateWorkspace          {commandId, workspaceId, workspaceName})                   -> CreateWorkspace.handle          offset            commandId workspaceId workspaceName
     (Just writeModel,RenameWorkspace          {commandId, workspaceId, workspaceNewName})                -> RenameWorkspace.handle          offset writeModel commandId workspaceId workspaceNewName
     (Just writeModel,SetGoal                  {commandId, workspaceId, goalId, goalDescription})         -> SetGoal.handle                  offset writeModel commandId workspaceId goalId goalDescription
     (Just writeModel,RefineGoalDescription    {commandId, workspaceId, goalId, refinedGoalDescription})  -> RefineGoalDescription.handle    offset writeModel commandId workspaceId goalId refinedGoalDescription
     (Just writeModel,StartWorkingOnGoal       {commandId, workspaceId, goalId})                          -> StartWorkingOnGoal.handle       offset writeModel commandId workspaceId goalId
     (Just writeModel,PauseWorkingOnGoal       {commandId, workspaceId, goalId})                          -> PauseWorkingOnGoal.handle       offset writeModel commandId workspaceId goalId
     (Just writeModel,NotifyGoalAccomplishment {commandId, workspaceId, goalId})                          -> NotifyGoalAccomplishment.handle offset writeModel commandId workspaceId goalId
     (Just writeModel,GiveUpOnGoal             {commandId, workspaceId, goalId, reason})                  -> GiveUpOnGoal.handle             offset writeModel commandId workspaceId goalId reason
     (Just writeModel,ActionizeOnGoal          {commandId, workspaceId, goalId, actionId, actionDetails}) -> ActionizeOnGoal.handle          offset writeModel commandId workspaceId goalId actionId actionDetails
     (Just writeModel,NotifyActionCompleted    {commandId, workspaceId, goalId, actionId})                -> NotifyActionCompleted.handle    offset writeModel commandId workspaceId goalId actionId
     (_            ,_)                                                                                    -> return $ CommandRejected "Scenario not handle"

我必须对字段进行模式匹配,并将它们传递给句柄....

EN

回答 2

Stack Overflow用户

发布于 2019-05-03 01:45:14

DataKinds创建新的种类和值,但不更改值的类型。CreateWorkspace值的类型仍然是GsdCommand,而不是'CreateWorkspace

一种选择是使用幻影类型,它不需要DataKinds扩展。

代码语言:javascript
复制
data CreateWorkspace
data RenameWorkspace

data GsdCommand t = GsdCommand CommandID WorkspaceID Text

handle :: Offset -> GsdCommand CreateWorkspace -> IO CommandHandlingResult
handle o (GsdCommand cmdID wkspID wkspName) = ...
票数 2
EN

Stack Overflow用户

发布于 2019-05-03 16:23:25

我已经在问题本身中添加了解决方案,但基本上我必须传递基于类的方式来表达问题,而不是使用基于替换的方法(使用Sum类型...)试着推广价值观。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55956320

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档