2016-09-30 18 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