无法通过动态映射:没有实例(Functor(Dynamic Spider))

时间:2018-04-13 09:04:16

标签: haskell haskell-stack ghcjs reflex reflex-dom

我的意图是在明亮的红色和黑暗之间交替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

我做错了什么?那个蜘蛛谁到底是谁?

1 个答案:

答案 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上获得。