在threepenny-gui中使用FRP和IORef

时间:2015-05-03 21:02:41

标签: haskell frp threepenny-gui

我在threepenny-gui(TPG)中使用了IORef的一个小例子:

testIORef :: IORef String -> Window -> UI ()
testIORef ref window = void $ do
    return window # set title "Test IORef"

    inCell  <- UI.input
    outCell <- UI.input

    -- When value changes write to IORef
    on  UI.valueChange inCell $ \_ -> do
        inValue <- get value inCell
        liftIO $ writeIORef ref inValue    

    -- function that reads the IORef and sets the value of an element with it
    let setValue oc = do  
            newVal <- liftIO $ readIORef ref
            element oc # set value newVal

    -- When enter is pressed update the value of the output
    on UI.keydown inCell $ \c -> if (c==13) then setValue outCell else return outCell

    getBody window #+ [ column [ grid [[string "In cell :", element inCell]
                                      ,[string "Out cell:", element outCell]
                                      ]
                                , string "Cells should update while typing."
                               ]
                      ]

我正在尝试将其更改为使用TPG中的Reactive内容。我已经从事件valueChange和keyDown:

制作了行为
inValue <- stepper "0" $ UI.valueChange inCell
inEnter <- stepper "0" $ fmap show $ filterE (\kc-> kc==13) $ UI.keydown inCell

但我仍然坚持如何使用这些行为来保存/获取IORef的值。问题是IORef调用将在UI monad中,所以如果我使用它们,行为将是Behavior (UI a),但是他们不会使用sink。我知道在这种情况下我不需要使用IORef(例如货币转换示例) - 但在我的实际情况下我会这样做。

编辑: 我尝试编写自己的属性:

valueUI :: ReadWriteAttr Element (UI String) String

这样我就可以使用Behavior (UI String)设置属性:

inEnter <- stepper "0" $ fmap show $ filterE (\kc-> kc==13) $ UI.keydown inCell    
let getValue = fmap (const $ liftIO $ readIORef ref) inEnter   
element outCell # sink valueUI getValue

代码编译但不起作用。

0 个答案:

没有答案