2016-09-30 3 views
1

В проекте PureScript Halogen я хотел бы установить состояние на случайное число, но как извлечь значение? НормальныйPurescript Halogen, побочный эффект (случайное число)

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 типа вар в настоящее время), чтобы сделать это возможным, а затем вы можете использовать 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, так как при использовании runUI он ожидает, что это будет Aff - можно cha Нге монада, используя interpret в Halogen.Component модуле, но так как вы просто использовать interpret liftAff в любом случае, вы можете также пойти прямо к Aff.)

Посмотрите на "Non-state effects" section of the guide или AJAX example для получения более подробной информации на запуск эффектов в eval.

Смежные вопросы