避免对类型类变量/类型族的未使用功能使用 contrete 类型

问题描述

我想为 Reflex 实现一个多层库,您可以在其中将客户端-服务器程序编写为单个值。 我遇到的问题是客户端和服务器具有不同的能力,但接口的客户端实现不应该支持服务器能力,反之亦然。

我可以想象这样一个(简化的)“WebM”类型类,具有明确分离的客户端和服务器类型:

class (Reflex c,Reflex s) => WebM c s m where
  type CM m :: * -> * -- Client context
  type SM m :: * -> * -- Server context
  liftClient :: CM m a -> m a
  liftServer :: SM m a -> m a
  -- Event occurrences received at client.
  toClient :: Event s a -> m (Event c a)
  -- Event occurrences received at server.
  toServer :: Event c a -> m (Event s a)
  ...

在这WebM monad 中,程序可能会要求服务器上下文支持数据库实现,并要求客户端支持 GUI:

example :: ( HasGui c (CM m),HasDatabase s (SM m),WebM c s m
           ) => m ()
example = do
  -- Uses GUI
  queries :: Event c Query <- 
      liftClient getInput
  queriesAtServer :: Event s Query <-
      toServer queries
  -- uses DB
  queryResults :: Event s Result <-
      liftServer (getResults queriesAtServer)
  -- Etc.
  ...

我第一次想到实现例如客户将在现有的 Reflex 时间线 t 和 monad m 上编写一个转换器,并为其提供 WebM 实现。 由于 WebM 类型类是如何编写来分隔层的,因此不可能触及“服务器”类型的值,因此程序对服务器的要求无关紧要,只要它需要什么客户要求。

我可以在下面的 ??? 点填写什么来实现这一目标,或者我可以使用更好的策略吗?

newtype ClientT t m a = ClientT ...

instance (Reflex t) => WebM t ??? (ClientT t m) where
  type CM (ClientT t m) = m
  type SM (ClientT t m) = ??? -- This can safely be anything
  toServer e = do
    -- Send messages to server
    pure ??? -- Absurd value.
  toClient e = do
    -- Listen for messages from server
    ...

我最初尝试了 Reflex 的“Void”实现(下面的尝试),但您仍然必须为程序可能会限制服务器/客户端实现的任何和所有类型类编写实例。这看起来很乏味。

data Voidflex :: *

newtype VoidM a = VoidM Void
  
instance Reflex Voidflex where
  newtype Behavior Voidflex a = Behavior { unB :: Void }
  newtype Event Voidflex a = Event { unE :: Void }
  newtype Dynamic Voidflex a = Dynamic { unD :: Void }
  type PullM Voidflex = VoidM
  type PushM Voidflex = VoidM
  ...

-- Would like to avoid:
instance HasDatabase Voidflex VoidM where
  ...

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...