0

我的意图是div在按下按钮时在亮红色和暗红色之间交替显示 a 的颜色,从暗红色开始。

我有这个代码:

{-# LANGUAGE
    OverloadedStrings
  #-}

module Main where

import Data.Map (Map)
import Reflex.Dom

main = mainWidget $ do
    x <- greenButton
    y <- toggle False x
    let z = fmap style y
    elDynAttr "div" z blank

style :: Bool -> Map String String
style b | b         = "style" =: "height: 10ex; width: 10ex; background-color: #f00;"
        | otherwise = "style" =: "height: 10ex; width: 10ex; background-color: #900;"

greenButton :: MonadWidget t m => m (Event t ())
greenButton = button "[ ]"  -- Should be green but whatever.

它因此出错:

• No instance for (Functor (Dynamic Spider))
    arising from a use of ‘fmap’
• In the expression: fmap style y
  In an equation for ‘z’: z = fmap style y
  In the second argument of ‘($)’, namely
    ‘do { x <- greenButton;
          y <- toggle False x;
          let z = fmap style y;
          elDynAttr "div" z blank }’

我当然在快速参考fmap中看到了一个for ,尽管我不确定参考的版本和 我编译的包的版本是否一致。Dynamicreflex

这是stack.yaml我用于构建的:

resolver: lts-7.19
compiler: ghcjs-0.2.1.9007019_ghc-8.0.1
compiler-check: match-exact

setup-info:
  ghcjs:
    source:
      ghcjs-0.2.1.9007019_ghc-8.0.1:
           url: http://ghcjs.tolysz.org/ghc-8.0-2017-02-05-lts-7.19-9007019.tar.gz
           sha1: d2cfc25f9cda32a25a87d9af68891b2186ee52f9

extra-deps:
- reflex-dom-0.3
- ghcjs-dom-0.2.4.0
- ref-tf-0.4.0.1
- reflex-0.4.0.1

allow-newer: true

我究竟做错了什么?而这个蜘蛛侠到底是谁?

4

1 回答 1

2

下面的讨论解释了为什么FunctorforDynamic原来是一个坏主意。

https://github.com/reflex-frp/reflex/pull/39

这个实例的问题在于,f只要输入动态变化,它就会计算两次:一次计算新Event值,一次计算新Behavior值。有了mapDyn,只有一次计算,两者的结果是共享的。这也是mapDynmonadic的原因。


所以代码看起来像这样:

main = mainWidget $ do
    x <- greenButton
    y <- toggle False x
    z <- mapDyn style y      -- monadic mapDyn instead of fmap
    elDynAttr "div" z blank

关于文档问题,Quickref.mdfor version 0.4.0.1is here and only references mapDyn

您链接到的Quickref.md是未来reflex-0.5的(当前develop分支),它正在修改Dynamic以拥有一个Functor实例。查看他们的维基

为什么 Dynamic 没有 Functor/Applicative/Monad 实例

Reflex 计划在 0.5 版中获取这些实例。在撰写本文时,该实现已基本完成,并且正在发布前进行最后的润色和测试,目前可在 github 的 reflex 开发分支中获得。

于 2018-04-13T10:46:48.903 回答