2016-09-30 51 views
1

在PureScript卤素项目中,我想将状态设置为随机数,但是如何提取该值?正常的Purescript卤素,副作用(随机数)

r <- randomInt 1 10 

当它在eval函数内部时不会编译。

module Main where 

import Prelude 
import Control.Monad.Eff (Eff) 
import Control.Monad.Eff.Random (randomInt, RANDOM) 
import Halogen as H 
import Halogen.HTML.Events.Indexed as HE 
import Halogen.HTML.Indexed as HH 
import Halogen.Util (runHalogenAff, awaitBody) 

type State = { n::Int } 

initialState :: State 
initialState = { n: 3} 

data Query a = NewRandom a 

ui :: forall e. H.Component { n :: Int } Query e 
ui = 
    H.component { render, eval } 
    where 
    render :: State -> H.ComponentHTML Query 
    render state = 
     HH.button 
      [ HE.onClick $ HE.input_ NewRandom ] 
      [ HH.text $ show state.n ] 


    eval :: Query ~> H.ComponentDSL State Query e 
    eval (NewRandom next) = do 
     H.modify (\state -> state { n=12 }) 

     --I'd like to set n to a random number 
     --but I don't know how. 
     --let r = randomInt 1 10 
     --H.modify (\state -> state { n=r }) 
     pure next 

main :: Eff (H.HalogenEffects()) Unit 
main = 
    runHalogenAff do 
    body <- awaitBody 
    H.runUI ui initialState body 

回答

3

您需要使用适当的单子与ComponentDSL(你有目前e类型VAR),使之可能,那么你可以使用H.fromEff解除randomInt

module Main where 

import Prelude 
import Control.Monad.Aff (Aff) 
import Control.Monad.Eff (Eff) 
import Control.Monad.Eff.Random (randomInt, RANDOM) 
import Halogen as H 
import Halogen.HTML.Events.Indexed as HE 
import Halogen.HTML.Indexed as HH 
import Halogen.Util (runHalogenAff, awaitBody) 

type State = { n::Int } 

initialState :: State 
initialState = { n: 3} 

data Query a = NewRandom a 

ui :: forall eff. H.Component { n :: Int } Query (Aff (random :: RANDOM | eff)) 
ui = 
    H.component { render, eval } 
    where 
    render :: State -> H.ComponentHTML Query 
    render state = 
     HH.button 
      [ HE.onClick $ HE.input_ NewRandom ] 
      [ HH.text $ show state.n ] 


    eval :: Query ~> H.ComponentDSL State Query (Aff (random :: RANDOM | eff)) 
    eval (NewRandom next) = do 
     r <- H.fromEff $ randomInt 1 10 
     H.modify (\state -> state { n=r }) 
     pure next 

main :: forall eff. Eff (H.HalogenEffects (random :: RANDOM | eff)) Unit 
main = 
    runHalogenAff do 
    body <- awaitBody 
    H.runUI ui initialState body 

(另外:如果你正在做有效的事情,即使你只需要Eff,使用Aff作为ComponentDSL monad是最容易的,因为当你使用runUI时,它期望它是Aff - 有可能cha NGE的单子中,Halogen.Component模块中使用interpret,但因为你只是使用interpret liftAff有反正,你不妨直接去Aff。)

"Non-state effects" section of the guide看看,或者AJAX example了解更多详情在运行效果eval