我在 WX 界面中使用 Reactive-Banana。按下按钮时,我需要从外部服务 API 检索值。
我有一个Behavior
基于数据类型的泛型AppState
,它基于函数转换(doSomeTransformation
)“累积”转换后的变化。getRemoteValue
转换后的值由事件传输,当按下界面上的按钮时,它们来自远程 API ( )。我编写了代表基本部分的代码的精简版本:
module Main where
{-# LANGUAGE ScopedTypeVariables #-} -- allows "forall t. Moment t"
import Graphics.UI.WX hiding (Event)
import Reactive.Banana
import Reactive.Banana.WX
{-----------------------------------------------------------------------------
Main
------------------------------------------------------------------------------}
data AppState = AppState {
count :: Int
} deriving (Show)
type String = [Char]
main :: IO ()
main = start $ do
f <- frame [text := "AppState"]
myButton <- button f [text := "Go"]
output <- staticText f []
set f [layout := margin 10 $
column 5 [widget myButton, widget output]]
let networkDescription :: forall t. Frameworks t => Moment t ()
networkDescription = do
ebt <- event0 myButton command
remoteValueB <- fromPoll getRemoteApiValue
myRemoteValue <- changes remoteValueB
let
doSomeTransformation :: AppState -> AppState
doSomeTransformation ast = ast { count = count ast }
coreOfTheApp :: Behavior t AppState
coreOfTheApp = accumB initialState $ (doSomeTransformation to combine with myRemoteValue) <$ ebt
sink output [text :== show <$> coreOfTheApp]
network <- compile networkDescription
actuate network
getRemoteApiValue :: IO Int
getRemoteApiValue = return 5
和阴谋集团:
name: brg
version: 0.1.0.0
synopsis: sample frp gui
-- description:
license: PublicDomain
license-file: LICENSE
author: me
maintainer: me@gmail.com
-- copyright:
category: fun
build-type: Simple
-- extra-source-files:
cabal-version: >=1.10
executable bgr
main-is: Main.hs
-- other-modules:
-- other-extensions:
build-depends: base >=4.7 && <4.8
, text
, wx ==0.92.0.0
, wxcore ==0.92.0.0
, transformers-base
, reactive-banana >=0.9 && <0.10
, reactive-banana-wx ==0.9.0.2
hs-source-dirs: src
default-language: Haskell2010
ghc-options: -Wall -O2
我的问题是如何编写doSomeTransformation
以及如何myRemoteValue
将远程 API 值用作普通事件值。
changes
来自banana-reactive 的签名如下:
changes :: Frameworks t => Behavior t a -> Moment t (Event t (Future a))
它将包装我IO Int
的getRemoteApiValue
。
所以基本上我怎么能从:
IO Int -> Moment t (Event t (Future AppState)) -> AppState
?
顺便说一句,我不确定拥有这个不同的函数签名是否更清晰:
doSomeTransformation :: Int -> AppState -> AppState
,其中Int
值由 API 返回值表示。听起来像是两个Behavior
s 和一个流。也许是解决问题的坏方法?