0

当我在玩 PureScript 时,我发现我想编写一个类型类Sync来等待任意异步值在Affmonad 中解析。我写的类型类是这样的:

class Sync s eff a where
  sync :: s -> Aff eff a

现在我想Sync为 websocket 连接创建实例,它会等到连接打开并且可用于读/写。我写的实例是这样的:

instance syncConnection :: Sync Connection (ws :: WEBSOCKET | eff) Unit where
  sync (Connection socket) =
    makeAff $ \fail continue ->
      set socket.onopen $ \_ ->
        continue unit

但是,我收到以下类型错误:

Type class instance head is invalid due to use of type

  ( ws :: WEBSOCKET
  | eff
  )

All types appearing in instance declarations must be of the form T a_1 .. a_n, where each type a_i is of the same form.

来自 Haskell,这对我来说很有意义——它反映了我需要启用FlexibleInstances扩展的情况,PureScript 似乎也不支持——但我想知道我是否可以实现我想要的泛型。

我想也许我可以调整我的Sync课程,然后创建一个新类型。

class Sync s m a where
  sync :: s -> m a

newtype WebSocketAff a = WebSocketAff (Aff (ws :: WEBSOCKET) a)

不幸的是,现在我又被困住了,因为我不知道有什么方法可以给出与我一开始遇到的类似原因WebSocketAff的实例。MonadAff

有什么技巧可以让我在不完全违背泛型目的的情况下让它工作吗?或者这种东西目前在 PureScript 中还不能真正表达?

4

2 回答 2

1

从编译器版本 0.10.3 开始,只要行是通过 FunDep 确定的,就可以在实例头中使用行:

例如

class Sync s eff a | s -> eff where -- FunDep here: eff is determinded via s
  sync :: s -> Eff eff a

data ConsoleSync = ConsoleSync

instance syncWithConsole :: Sync ConsoleSync (console :: CONSOLE | eff) Unit where
  sync _ = log "hello"

foo :: ∀ eff. Eff (console :: CONSOLE | eff) Unit
foo = sync ConsoleSync

发行说明 v0.10.3:https ://github.com/purescript/purescript/releases/tag/v0.10.3

于 2016-12-13T20:04:29.190 回答
-1

我在我的移动 ATM 上,所以我无法测试这个,但你尝试使用 forall 吗?

instance syncConnection :: forall eff. Sync Connectionync Connection . . .

于 2016-05-31T21:23:14.370 回答