在三便士中使用 IORef
Using IORef in threepenny gui
我试图在 threepenny-gui 中设置一个 IORef,但我无法让它工作。在我的应用程序中,IORef 本身会更复杂并且不会显示本身 - 但这个示例演示了我认为的问题。
这是我的尝试:
testIORef2 :: IORef String -> Window -> UI ()
testIORef2 ref window = void $ do
return window # set title "Test IORef"
inCell <- UI.input
outCell <- UI.input
getBody window #+ [
column [
grid [[string " In cell::", element inCell]
,[string "Out cell::" , element outCell ]]
, string "Cells should update while typing."
]]
-- When value changes write to IORef
on UI.valueChange inCell $ \_ -> do
inValue <- get value inCell
liftIO $ writeIORef ref inValue
-- Read the IORef
refVal <- liftIO $ readIORef ref
-- Behaviour which holds the string value in the input cell
inValue <- stepper "0" $ UI.valueChange inCell
-- Behaviour which holds the value in the ref
let outValue = (const refVal) <$> inValue
-- Set the value of the output cell to the outValue
element outCell # sink value outValue
代码可以正常工作,但 outValue 不是最新的。
如何修复它以便及时更新。此外,欢迎对代码进行任何改进。
谢谢。
我不是 threepenny-gui 的专家,但这是我的猜测。
您在外部 on
事件处理程序编写的代码仅执行一次。因此,您希望在 outValue
更新 内包含 所述处理程序,例如
-- When value changes write to IORef
on UI.valueChange inCell $ \_ -> do
inValue <- get value inCell
liftIO $ writeIORef ref inValue
... -- compute outValue
element outCell # sink value outValue
你写的代码可能不是你想要做的。行
let outValue = (const refVal) <$> inValue
指定outValue
是一个Behavior
,其值是常量,等于refValue
。反过来,后面的值是从
中得到的
refVal <- liftIO $ readIORef ref
这意味着它是 IORef
在这个时间点存储在 UI
monad 中的值。
当使用IORef
时,你想在发生变化时读取引用的值,并使用这个值来修改UI内容,例如这样:
on UI.valueChange inCell $ \_ -> do
inValue <- get value inCell
liftIO $ writeIORef ref inValue
outValue <- liftIO $ readIORef ref
element outCell # set value outValue
出于一致性(操作顺序)的原因,不建议使用 IORef
作为 Behavior
的来源——它要么是后者,要么是前者。
我试图在 threepenny-gui 中设置一个 IORef,但我无法让它工作。在我的应用程序中,IORef 本身会更复杂并且不会显示本身 - 但这个示例演示了我认为的问题。
这是我的尝试:
testIORef2 :: IORef String -> Window -> UI ()
testIORef2 ref window = void $ do
return window # set title "Test IORef"
inCell <- UI.input
outCell <- UI.input
getBody window #+ [
column [
grid [[string " In cell::", element inCell]
,[string "Out cell::" , element outCell ]]
, string "Cells should update while typing."
]]
-- When value changes write to IORef
on UI.valueChange inCell $ \_ -> do
inValue <- get value inCell
liftIO $ writeIORef ref inValue
-- Read the IORef
refVal <- liftIO $ readIORef ref
-- Behaviour which holds the string value in the input cell
inValue <- stepper "0" $ UI.valueChange inCell
-- Behaviour which holds the value in the ref
let outValue = (const refVal) <$> inValue
-- Set the value of the output cell to the outValue
element outCell # sink value outValue
代码可以正常工作,但 outValue 不是最新的。
如何修复它以便及时更新。此外,欢迎对代码进行任何改进。
谢谢。
我不是 threepenny-gui 的专家,但这是我的猜测。
您在外部 on
事件处理程序编写的代码仅执行一次。因此,您希望在 outValue
更新 内包含 所述处理程序,例如
-- When value changes write to IORef
on UI.valueChange inCell $ \_ -> do
inValue <- get value inCell
liftIO $ writeIORef ref inValue
... -- compute outValue
element outCell # sink value outValue
你写的代码可能不是你想要做的。行
let outValue = (const refVal) <$> inValue
指定outValue
是一个Behavior
,其值是常量,等于refValue
。反过来,后面的值是从
refVal <- liftIO $ readIORef ref
这意味着它是 IORef
在这个时间点存储在 UI
monad 中的值。
当使用IORef
时,你想在发生变化时读取引用的值,并使用这个值来修改UI内容,例如这样:
on UI.valueChange inCell $ \_ -> do
inValue <- get value inCell
liftIO $ writeIORef ref inValue
outValue <- liftIO $ readIORef ref
element outCell # set value outValue
出于一致性(操作顺序)的原因,不建议使用 IORef
作为 Behavior
的来源——它要么是后者,要么是前者。