我的意图是在明亮的红色和黑暗之间交替div
的颜色
红色按下按钮,从深红色开始。
我有这段代码:
{-# 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 }’
我确实在quick reference中看到了fmap
Dynamic
,
虽然我不确定参考的版本和版本
我编译的reflex
包是一致的。
这是我用于构建的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
我做错了什么?那个蜘蛛谁到底是谁?
答案 0 :(得分:2)
下面的讨论解释了为什么Functor
Dynamic
被证明是个坏主意。
https://github.com/reflex-frp/reflex/pull/39
此实例的问题在于,只要输入动态发生变化,它就会评估
f
两次:一次计算新Event
值,一次计算新Behavior
值。对于mapDyn
,只有一个计算,两者的结果是共享的。这也是mapDyn
是monadic的原因。
所以代码看起来像这样:
main = mainWidget $ do
x <- greenButton
y <- toggle False x
z <- mapDyn style y -- monadic mapDyn instead of fmap
elDynAttr "div" z blank
关于文档问题,Quickref.md
for version 0.4.0.1
is here并且仅引用mapDyn
。
您链接到的Quickref.md
是未来的reflex-0.5
develop
(当前Dynamic
分支),正在重新Functor
以获得const
实例。 See their wiki:
为什么动态没有Functor / Applicative / Monad实例
Reflex计划在0.5版本中获取这些实例。在撰写本文时,实现大部分已完成,并且在发布之前正在进行最终的修改和测试,目前可以在reflex的开发分支的github上获得。