Purescript卤素,副作用(随机数) [英] Purescript Halogen, side effect (random number)

查看:170
本文介绍了Purescript卤素,副作用(随机数)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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

解决方案

您需要在ComponentDSL(当前具有e类型var的地方)中使用适当的monad,然后才能进行操作使用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-可以使用Halogen.Component模块中的interpret更改单子,但是由于您无论如何都只是在其中使用interpret liftAff,您也可以直接转到Aff.)

看看指南的非状态影响"部分,或 AJAX示例,详细了解eval中的运行效果.

In a PureScript Halogen project, I would like to set the state to a random number, but how do I extract the value? The normal

r <- randomInt 1 10

does not compile when it's inside the eval function.

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

解决方案

You need to use an appropriate monad with your ComponentDSL (where you have the e type var currently) to make it possible, and then you can use H.fromEff to lift the 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

(Aside: If you're doing effectful things, even if you only need Eff, it's easiest to use Aff as the ComponentDSL monad, as when you use runUI it expects it to be Aff - it is possible to change the monad, using interpret in the Halogen.Component module, but since you'd just be using interpret liftAff there anyway, you may as well go straight to Aff.)

Take a look at the "Non-state effects" section of the guide, or the AJAX example for more details on running effects in eval.

这篇关于Purescript卤素,副作用(随机数)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆