仅适用于某种类型的构造函数的函数

Sea*_*ess 6 haskell types message-queue data-kinds

我正在为消息队列编写一个lib.队列可以是DirectTopic.Direct队列具有静态绑定密钥,而Topic队列可以具有动态密钥.

我想编写一个publish仅适用于Direct队列的函数.这有效:

{-# LANGUAGE DataKinds #-}

type Name = Text
type DirectKey = Text
type TopicKey = [Text]

data QueueType
  = Direct DirectKey
  | Topic TopicKey

data Queue (kind :: a -> QueueType)
  = Queue Name QueueType
Run Code Online (Sandbox Code Playgroud)

这需要两个独立的构造函数

directQueue :: Name -> DirectKey -> Queue 'Direct

topicQueue :: Name -> TopicKey -> Queue 'Topic
Run Code Online (Sandbox Code Playgroud)

但是当我去编写发布时,我需要匹配一个额外的模式,这是不可能的

publish :: Queue 'Direct -> IO ()
publish (Queue name (Direct key)) =
   doSomething name key
publish _ =
   error "should be impossible to get here"
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来模拟这个问题,以便我不需要这种模式匹配?Direct队列应始终具有该Text元数据,并且Topic队列应始终具有该[Text]元数据.有没有更好的方法在类型和价值级别强制执行此操作?

dan*_*iaz 6

如何制作Queue一个简单的多态类型

data Queue a = Queue Name a
Run Code Online (Sandbox Code Playgroud)

然后定义单独的Queue DirectKeyQueue TopicKey类型?那你就不需要模式匹配了publish :: Queue DirectKey -> IO ().

如果,除此之外,你需要应在任何工作的功能Queue,也许你可以定义在一个类型类一些常用的操作DirectKey,并TopicKey会实例,然后有像签名

commonFunction :: MyTypeclass a => Queue a -> IO ()
Run Code Online (Sandbox Code Playgroud)

也许你可以将这些函数直接放在类型类中

class MyTypeclass a where
    commonFunction :: Queue a -> IO ()
Run Code Online (Sandbox Code Playgroud)