所以,从逻辑上讲,我看到这是如何工作的,但是,我找不到工作的Haskell语法来表达逻辑。这是我对嵌套警卫的尝试,显然这不是一个受支持的功能:
data Tree a where
Nil :: Tree a
Node :: Ord a => Tree a -> a -> Tree a -> Tree a
-- Get the nth top element of a sorted binary tree:
getNthElement :: Int -> Tree a -> Either Int a
getNthElement _ Nil = Left 0
getNthElement n (Node l v r)
| (Right x) <- rightRecurse = rightRecurse
| (Left nr) <- rightRecurse, nr == n = Right v
| (Left nr) <- rightRecurse
| (Right x) <- leftRecurse = leftRecurse
| (Left nl) <- leftRecurse = Left $ nl + nr + 1
where leftRecurse = getNthElement (n-nr-1) l in
where rightRecurse = getNthElement n r
答案 0 :(得分:1)
感谢bheklilr,案例表达解决了这个问题。工作代码是:
## app.R ##
library(shiny)
library(shinydashboard)
library(shinyjs)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody(
actionButton(inputId = "btn_data", label = "Download"),
conditionalPanel(condition = "output.setupComplete",
box( title = "box1" ),
box( title = "box2" ),
box( title = "boc3" )
),
conditionalPanel(condition = "!output.setupComplete",
box( title = "loading"))
)
)
server <- function(input, output) {
rv <- reactiveValues()
rv$setupComplete <- FALSE
## simulate data load
observe({
if(input$btn_data){
df <- data.frame(id = seq(1,200),
val = rnorm(200, 0, 1))
## Simulate the data load
Sys.sleep(5)
## set my condition to TRUE
rv$setupComplete <- TRUE
}
## the conditional panel reads this output
output$setupComplete <- reactive({
return(rv$setupComplete)
})
outputOptions(output, 'setupComplete', suspendWhenHidden=FALSE)
})
}
shinyApp(ui, server)
答案 1 :(得分:0)
这就是我写它的方式(我已将所有内容放在self-contained gist以防你想玩它)。 State Int
monad处理计数器的线程,Maybe
替代选择正确的值。我认为这种算法更具可读性。
我们从一堆导入和您对Tree
的定义开始:
{-# LANGUAGE GADTs #-}
module NthElement where
import Data.Functor
import Control.Applicative
import Control.Monad
import Control.Monad.Trans.State
data Tree a where
Nil :: Tree a
Node :: Ord a => Tree a -> a -> Tree a -> Tree a
然后我们得出主要定义:getNthElement
运行有状态计算,如果我们返回Nothing
,它会放置被访问节点的数量(原始数量减去最终Int
状态),否则它会返回它找到的值。
getNthElement :: Int -> Tree a -> Either Int a
getNthElement k t = maybe (Left $ k - s) Right mv where
(mv , s) = go t `runState` k
go :: Tree a -> State Int (Maybe a)
有状态计算本身是对算法的高级描述的直接翻译:
如果我们找到Nil
,则没有值返回(因此我们失败了)
go Nil = return Nothing
如果我们找到Node
,那么我们要查找的第n个值是在正确的子树中,如果在探索到正确的子树后计数器是0
,则在中间,或者在左子树的某处:
go (Node l v r) = do
rv <- go r
k <- get
() <- put $ k - 1
lv <- go l
return $ rv <|> (v <$ guard (k == 0)) <|> lv
有了这个定义,我们就不会立即开始做不需要的工作(我们写的是lv <- go l
,当时可能已经找到了值!)。然而,懒惰在我们这边,并说服自己确实没问题,我们可以定义一个左无限树并观察getNthElement
总是返回一个值:
leftInfTree :: Tree Int
leftInfTree = foldr (\ k ih -> Node ih k Nil) Nil [1..]
在ghci中测试:
*NthElement> getNthElement 10 leftInfTree
Right 11