Невозможно отобразить через Dynamic: нет экземпляра для (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 }’
Я конечно вижу 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 ответ
Обсуждение ниже объясняет, почему Functor
за Dynamic
оказалась плохой идеей.
https://github.com/reflex-frp/reflex/pull/39
Проблема с этим экземпляром в том, что он будет оценивать
f
дважды, когда изменяется входная динамика: один раз для вычисления новогоEvent
значение и один раз для вычисления новогоBehavior
значение. СmapDyn
, есть только одно вычисление, результат обоих является общим. Это также почемуmapDyn
монадический
Таким образом, код будет выглядеть так:
main = mainWidget $ do
x <- greenButton
y <- toggle False x
z <- mapDyn style y -- monadic mapDyn instead of fmap
elDynAttr "div" z blank
По вопросу документации, Quickref.md
для версии 0.4.0.1
здесь и только ссылки mapDyn
,
Quickref.md
Вы связаны с тем, на будущее reflex-0.5
(электрический ток develop
филиал), который переделывает Dynamic
иметь Functor
пример. Смотрите их вики:
Почему в Dynamic нет экземпляров Functor/Applicative/Monad
Рефлекс планируется получить эти экземпляры в версии 0.5. На момент написания этой статьи реализация в основном завершена и проходит окончательную доработку и тестирование перед выпуском и в настоящее время доступна на github в ветке разработки reflex.