1

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 モナドにあることです。したがって、それらを使用すると、動作は になりますが、動作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

コードはコンパイルされますが、機能しません。

4

0 に答える 0