Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 试图以特殊行为在三便士gui中呈现字段_Haskell_User Interface_Threepenny Gui - Fatal编程技术网

Haskell 试图以特殊行为在三便士gui中呈现字段

Haskell 试图以特殊行为在三便士gui中呈现字段,haskell,user-interface,threepenny-gui,Haskell,User Interface,Threepenny Gui,我想做的是设置字段,当它们处于焦点时显示细节,但当它们不处于焦点时显示摘要。例如 a) 。当它失去焦点(变得模糊?)时,我将该值保存在(状态?)映射中,然后将该值更改为旧值的函数(即摘要值) b) 。当它获得焦点时-我用保存在映射中的旧值替换摘要值 我不知道怎么做,但我想我可能需要一个状态monad和UI monad。我的尝试是: renderField :: Map->Int->UI (Element, Map) renderField vs ix = do input &

我想做的是设置字段,当它们处于焦点时显示细节,但当它们不处于焦点时显示摘要。例如

a) 。当它失去焦点(变得模糊?)时,我将该值保存在(状态?)映射中,然后将该值更改为旧值的函数(即摘要值)

b) 。当它获得焦点时-我用保存在映射中的旧值替换摘要值

我不知道怎么做,但我想我可能需要一个状态monad和UI monad。我的尝试是:

renderField :: Map->Int->UI (Element, Map)
renderField vs ix = do
    input <- UI.input  
    on UI.blur input $ \_ -> void $ do
        fieldValue <- get value input
        let newVs = insert ix fieldValue vs
        return input # set UI.value (calcNewValue fieldValue)
    on UI.focus input $ \_ -> void $ do
        let savedValue = findWithDefault "" ix vs
        return input # set UI.value savedValue
    return (input, newVs)
renderField::Map->Int->UI(元素,映射)
renderField vs ix=do
输入void$do
字段值无效$do
让savedValue=findWithDefault“ix vs
返回输入#设置UI.value保存值
返回(输入,newVs)
但是我无法让这张地图正常工作,因为它需要跟踪所有的电话。。。。我想应该是单子还是什么

谢谢


N

事实上,您需要跟踪状态

但是,通常的模式
s->(a,s)
(状态monad)在这里不适用,因为您正在使用回调函数。对于这些,您需要不同的模式

在传统的命令式风格中,这里可以使用可变变量,例如
IORef
。请注意,不再需要跟踪索引——您可以将
IORef
视为大型可变映射中的索引

renderField :: UI Element
renderField = do
    input <- UI.input
    state <- liftIO $ newIORef

    on UI.blur input $ \_ -> do
        fieldValue <- get value input
        liftIO $ writeIORef state fieldValue    
        element input # set UI.value (calcNewValue fieldValue)

    on UI.focus input $ \_ -> do
        savedValue <- liftIO $ readIORef state
        element input # set UI.value savedValue

    return input
同样,在这段代码中仍然有一些微妙之处和缺点,但这是我想要进入的一般方向。有关FRP及其如何应用于GUI开发的初步信息,请参阅

我的建议是,当您需要快速完成任务时,使用熟悉的解决方案(
IORef
),当您有充足的空闲时间时,探索FRP解决方案。主要采用FRP型


(披露:我是《三便士》的作者。)

这似乎很复杂。为什么不让数据保持不变,让渲染器在决定显示什么时检查焦点?这个例子怎么样?比如说,我输入6+2,当它处于焦点时显示6+2,当它失去焦点时显示8,并将6+2保存到某个地方。当它重新聚焦时,再次显示6+2。这将如何工作?存储输入的值。当它模糊时,显示评估值。第一个选项不编译,因为IOref在IO monad中,而不是UI monad中-我正在努力将liftIO放在正确的位置。第二个选项——我最喜欢的选项——在bValueUser前面需要一个常量(accumB的第二个参数需要一个[Char]->[Char])。谢谢。@b1g3ar5谢谢您的更正,显然我没有试图编译代码。:)现在应该修复了。另一个小编辑-我认为calcNewValue应该应用于bValueUser,否则该字段在模糊上落后一步。@b1g3ar5对!这就引出了一个问题,为什么我们首先需要
bState
。我认为只要
UI.valueChange
确实只在用户输入时改变(这是我的初衷),它就可以被
bValueUser
取代。不管怎么说,你明白了,无论是总体上还是我提到的微妙之处。
renderField :: UI Element
renderField = do
    input  <- UI.input

    bValueUser <- stepper "" $ UI.valueChange input
    bState     <- stepper "" $ bValueUser <@ UI.blur input
    bValue     <- stepper "" $ fmap head $ unions
        [ (calcNewValue <$> bValueUser) <@ UI.blur input
        , bState <@ UI.focus input
        ]
    element input # sink UI.value bValue