【问题标题】:Polymorphic instruction in Free Monad in PurescriptPurescript 中的 Free Monad 中的多态指令
【发布时间】:2015-10-24 13:53:49
【问题描述】:

我正在尝试编译这段小代码。

module Sodium where

import Prelude
import Control.Monad.Free
import Data.Coyoneda
import Data.Tuple

data ReactiveF more
  = RFNewEvent (forall a. (Tuple (Event a) (a -> Reactive Unit) -> more))

type Reactive a = FreeC ReactiveF a

data Event a = Event a

newEvent :: forall a. Reactive (Tuple (Event a) (a -> Reactive Unit))
newEvent = liftFC $ RFNewEvent id

如果我在 RFNewEvent 中使用“数字”而不是“a”,那么一切都可以正常编译。但是当我去“forall a”的那一刻。并将“Number”替换为“a”,它不再编译。

我收到以下错误消息

Cannot unify type
  a1
with type
  a0

有人知道怎么做吗?

我正在使用 0.5.0 版的 purescript-free。

编辑

如果我使用以下内容

data NewEventData = NewEventData forall a. Tuple (Event a) (a -> Reactive Unit)

并将其替换为RFNewEvent,然后它将编译。但我最终得到了一个不想要的 newEvent 类型签名。

newEvent :: Reactive NewEventData
newEvent = liftFC $ RFNewEvent id

这让我可以创建一个事件,但让我可以将不同的事件值而不是相同类型的值发送到事件流。 (缺少 forall a. 现在在 newEvent 上)

我可能犯了一个错误。

总体目标是使用 Free Monad 模拟 SodiumFRP 的界面。然后在解释 Free Monad 时通过 FFI 插入与 Sodium 类似的现有 JavaScript FRP 库。

这可能吗?

【问题讨论】:

  • 我怀疑你想要一个存在量词,而不是一个全称量词?你见过purescript-exists吗?
  • 不,我还没有看到纯脚本存在。现在看看它。虽然我可能在设计中犯了错误。
  • @菲尔弗里曼。是的,你在写。 purescript-exists 使得定义“样本”成为可能。 (下一部分我被卡住了)

标签: purescript free-monad


【解决方案1】:

以下代码现在可以编译并具有“newEvent”所需的类型签名

module FRP.Sodium where

import Prelude
import Control.Monad.Free
import Data.Coyoneda
import Data.Tuple

data ReactiveF more
  = RFNewEvent (NewEventData -> more)

type Reactive a = FreeC ReactiveF a

data NewEventData = NewEventData forall a. Tuple (Event a) (a -> Reactive Unit)

data Event a
  = ENever
  | EMerge (Event a) (Event a)
  | EFilterJust (Event (Maybe a))
  | ECoalesce (a -> a -> a) (Event a)
  | EOnce (Event a)
  | ESplit (Event (Array a))
  | EVar Int

data Behaviour a = BVar Int

extractNewEventData :: forall a. NewEventData -> (Tuple (Event a) (a -> Reactive Unit))
extractNewEventData (NewEventData x) = x

newEvent :: forall a. Reactive (Tuple (Event a) (a -> Reactive Unit))
newEvent = map extractNewEventData $ liftFC $ RFNewEvent id

编辑

还尝试了 purescript-exists。可以定义“样本”

RFSample 被添加到 ReactiveF ...

.
.
.
data ReactiveF more
  = RFNewEvent (NewEventData -> more)
  | RFSample (SampleData more)
.
.
.
data SampleDataF more a = SampleDataF (Behaviour a) (a -> more)
type SampleData more = Exists (SampleDataF more)

sample :: forall a. Behaviour a -> Reactive a
sample beh = liftFC $ RFSample $ mkExists $ SampleDataF beh id

感谢菲尔弗里曼的评论。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-28
    • 1970-01-01
    • 2021-09-04
    • 1970-01-01
    • 1970-01-01
    • 2019-11-27
    相关资源
    最近更新 更多