输入变量错误

时间:2017-12-14 23:10:08

标签: haskell types

我目前正在研究Haskell中的游戏引擎,现在我正在尝试在此引擎的子系统之间实现消息传递系统(我正在使用Publisher-Subscriber模式)。您可以在here on my github profile查看整个代码。我实施了一个"参与者"参与我的Messaging系统的所有数据类型的类型类,如下所示:

class (Show m, Message m) => Participant prt m where
  -- | Function to get the lsit of subscribers from the participant
  partSubscribers
    :: prt
    -- ^ the participant
    -> forall us. Affection us [(m -> Affection us ())]
    -- ^ List of Subscriber functions

  -- | Subscribe to the 'Participant''s events
  partSubscribe
    :: prt
    -- ^ The 'Participant' to subscribe to
    -> (forall us. m -> Affection us ())
    -- ^ What to do in case of a 'Message'
    -- (Subscriber function)
    -> Affection us UUID
    -- ^ 'UUID' of the registered subscriber Function

  -- | Unsubscribe a Subscriber function from Participant
  partUnSubscribe
    :: prt             -- ^ The 'Participant' to unsubscribe from
    -> UUID            -- ^ The subscriber function's 'UUID'
    -> Affection us ()

  -- | Get the 'Participant' to emit a 'Message' on all of its subscribers
  partEmit
    :: prt             -- ^ The 'Participant'
    -> m               -- ^ The 'Message' to emit
    -> Affection us ()
  partEmit p m = do
    liftIO $ logIO Debug $ "Emitting message: " ++ show m
    l <- partSubscribers p
    mapM_ ($ m) l

这个类型类的具体实现看起来像这样。我正在使用套餐stm

data AffectionWindow us = AffectionWindow
  { windowSubscribers
      :: forall us. TVar [(UUID, WindowMessage -> Affection us ())]
  }

instance Participant (AffectionWindow us) WindowMessage where
  partSubscribe p funct = do
    uuid <- genUUID
    liftIO $ atomically $ modifyTVar' (windowSubscribers p) ((uuid, funct) :)
    return uuid

  partUnSubscribe p uuid =
    liftIO $ atomically $ modifyTVar' (windowSubscribers p)
      (filter (\(u, _) -> u /= uuid))

  partSubscribers p = do
    subTups <- liftIO $ readTVarIO $ windowSubscribers p
    return $ map snd subTups

这段代码编译得很好,但是当我尝试在最小的例子中使用它时,它无法编译。它失败的代码如下所示:

load :: IO StateData
load = do
  empty1 <- newTVarIO []
  -- ([] :: [(UUID, WindowMessage -> Affection StateData ())])
  empty2 <- newTVarIO []
  -- ([] :: [(UUID, MouseMessage -> Affection StateData ())])
  empty3 <- newTVarIO []
  -- ([] :: [(UUID, KeyboardMessage -> Affection StateData ())])
  return $ StateData $ Subsystems
    (AffectionWindow empty1)
    (AffectionMouse empty2)
    (AffectionKeyboard empty3)

,错误信息为:

examples/example00.hs:43:22: error:
    • Couldn't match type ‘a0’
                     with ‘(UUID, WindowMessage -> Affection us1 ())’
        because type variable ‘us1’ would escape its scope
      This (rigid, skolem) type variable is bound by
        a type expected by the context:
          forall us1. TVar [(UUID, WindowMessage -> Affection us1 ())]
        at examples/example00.hs:43:6-27
      Expected type: TVar [(UUID, WindowMessage -> Affection us1 ())]
        Actual type: TVar [a0]
    • In the first argument of ‘AffectionWindow’, namely ‘empty1’
      In the first argument of ‘Subsystems’, namely
        ‘(AffectionWindow empty1)’
      In the second argument of ‘($)’, namely
        ‘Subsystems
           (AffectionWindow empty1)
           (AffectionMouse empty2)
           (AffectionKeyboard empty3)’
    • Relevant bindings include
        empty1 :: TVar [a0] (bound at examples/example00.hs:39:3)
   |
43 |     (AffectionWindow empty1)
   |                      ^^^^^^

我从来没有遇到过这样的错误,而且我的智慧结束了。 希望有人在这里知道解决方案。

谢谢你的时间!

0 个答案:

没有答案