无法通过动态映射:没有实例 (Functor (Dynamic Spider))
Cannot map through Dynamic: No instance for (Functor (Dynamic Spider))
我的意图是让 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 中看到 Dynamic
的 fmap
,
虽然我不确定参考的版本和
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
我做错了什么?这个蜘蛛侠到底是谁?
下面的讨论解释了为什么 Functor
对于 Dynamic
结果是个坏主意。
https://github.com/reflex-frp/reflex/pull/39
The problem with this instance is that it will evaluate f
twice whenever the input dynamic changes: once to compute the new Event
value, and once to compute the new Behavior
value. With mapDyn
, there is only a single computation, the result of both is shared. This is also why mapDyn
is 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
实例。 See their wiki:
Why doesn't Dynamic have Functor/Applicative/Monad instances
Reflex is scheduled to get these instances in version 0.5. As of this writing the implementation is mostly complete and is undergoing final polish and testing before release and is currently available on github in reflex's develop branch.
我的意图是让 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 中看到 Dynamic
的 fmap
,
虽然我不确定参考的版本和
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
我做错了什么?这个蜘蛛侠到底是谁?
下面的讨论解释了为什么 Functor
对于 Dynamic
结果是个坏主意。
https://github.com/reflex-frp/reflex/pull/39
The problem with this instance is that it will evaluate
f
twice whenever the input dynamic changes: once to compute the newEvent
value, and once to compute the newBehavior
value. WithmapDyn
, there is only a single computation, the result of both is shared. This is also whymapDyn
is 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
实例。 See their wiki:
Why doesn't Dynamic have Functor/Applicative/Monad instances
Reflex is scheduled to get these instances in version 0.5. As of this writing the implementation is mostly complete and is undergoing final polish and testing before release and is currently available on github in reflex's develop branch.