如何在' do'中访问Writer monad的值和累加器。 block(PureScript)?

时间:2016-09-16 01:49:43

标签: monads purescript writer-monad

我现在正在了解Writer monad,而且我不确定是否想要在{{1}内读取monad的值和累加器是否正确阻止。例如,在下面的coltzSeq函数中,我想读取Array累加器的长度作为函数的最终计算。是否可以这样做或者这是对Writer的错误使用?显然,我可以让调用者读取最终数组的长度,或者我可以使用State monad,但这对我来说只是一个练习。

do

编辑: 我尝试了gb。的建议,并尝试使用类型为module Main where import Prelude import Data.Tuple import Control.Monad.Writer import Math (remainder, (%)) import Data.Int (toNumber, fromNumber) import Control.Monad.Eff.Console (logShow) coltz :: Number -> Number coltz n = case (n % 2.0 == 0.0) of true -> n / 2.0 false -> 3.0 * n + 1.0 coltzW :: Number -> Writer (Array Number) Number coltzW n = do tell [n] pure $ coltz n -- Computes a coltz sequence and counts how many -- steps it took to compute coltzSeq :: Number -> Writer (Array Number) Int coltzSeq n = do -- Can read the value in the writer -- but not the writer's internal state v <- (coltzW n) let l = 1 -- Can read the value and the internal -- state, but it's not bound to the monad's context. -- let a = runWriter (coltzW n) -- let v = fst a -- let l = length (snd a) case (v) of 1.0 -> pure $ l _ -> to1 v 的{​​{1}}函数。如果我们在此上下文中使用listens,则类型为...

(Monoid w, Monad m) => forall w m a b. MonadWriter w m => (w -> b) -> m a -> m (Tuple a b)

因此id接受MonadWriter w m => (w -> b) -> m a -> m (Tuple a b) w = Array Number m = WriterT (Array Number) Identity (alias: Writer (Array Number) ) b = Array Number a = Number (Array Number -> Array Number) -> Writer (Array Number) Number -> Writer (Array Number) (Tuple Number (Array Number)) ,并返回一个值为当前Writer状态的Writer(因为我们使用了listens id)。但是,我一直在尝试使用Writer (Array Number) Number)

的所有方式获取类型错误
id

EDIT2: 我想出了我需要做什么。出于某种原因,我需要在使用listens时添加类型注释。

to1 :: Number -> (Writer (Array Number)) Int
to1 n = do
  v <- (coltzW n)
  -- a <- snd <$> listens id
  -- let l = snd <$> (listens id (execWriter (coltzW n)))
  -- let l = execWriter (listens id (coltzW n))

  -- Seems like this one should work to get Array Number
  -- let l = snd <$> (listens id (coltzW n))

  case (v) of
    1.0 -> pure 1
    _   -> to1 v

2 个答案:

答案 0 :(得分:1)

我认为listens是您正在寻找的功能:https://pursuit.purescript.org/packages/purescript-transformers/1.0.0/docs/Control.Monad.Writer#v:listens,如果我正确理解您正在尝试做什么。

如果您对转换价值不感兴趣,可以传递id,如果您只想获得累计值,那么a <- snd <$> listens id就可以了。

答案 1 :(得分:0)

您无法访问当前累加器。 Writer是只写的。如果需要当前累加器,请使用State代替Writerlisten只能为您提供已完成计算的累加器。