Operational monad with interpreter in arbitrary monad
Date : March 29 2020, 07:55 AM
this one helps. That's because the m in the local type signatures are fresh type variables, so they promise to work with any Monad. If you use display, eval can only work for the specific monad display uses. It should work if you a) remove the local type signatures, or b) bring the type variable m into scope {-# LANGUAGE ScopedTypeVariables #-}
...
interpret :: forall m. (Int -> m ()) -> Elo a -> Int -> m a
|
Create my own state monad transformer module hiding underlying state monad
Date : March 29 2020, 07:55 AM
may help you . I think that if you can write an instance of MonadState for your transformer you can use modify without the lift: instance Monad m => MonadState (ZipperT s m a) where
...
MonadState (ZipperState s) (ZipperT s m)
instance MonadState s m => MonadState s (ZipperT s m) where
...
getZ :: Monad m => ZipperT s m (ZipperState s)
getZ = ZipperT_ get
putZ :: Monad m => ZipperState s -> ZipperT s m ()
putZ = ZipperT_ . put
modifyZ :: Monad m => (ZipperState s -> ZipperState s) -> ZipperT s m ()
modifyZ = ZipperT_ . modify
-- This requires UndecidableInstances
instance MonadState s m => MonadState s (ZipperT a m) where
get = lift get
put = lift . put
length' :: [a] -> Int
length' xs = runIdentity (execStateT (runZipperT contar ([], xs)) 0)
where contar :: ZipperT a (StateT Int Identity) ()
contar = headR >>= \x -> case x of
Nothing -> return ()
Just _ -> do
right2left
modify (+ (1::Int))
-- ^^^^^^^
contar
|
Why must we use state monad instead of passing state directly?
Date : March 29 2020, 07:55 AM
seems to work fine State passing is often tedious, error-prone, and hinders refactoring. For example, try labeling a binary tree or rose tree in postorder: data RoseTree a = Node a [RoseTree a] deriving (Show)
postLabel :: RoseTree a -> RoseTree Int
postLabel = fst . go 0 where
go i (Node _ ts) = (Node i' ts', i' + 1) where
(ts', i') = gots i ts
gots i [] = ([], i)
gots i (t:ts) = (t':ts', i'') where
(t', i') = go i t
(ts', i'') = gots i' ts
preLabel :: RoseTree a -> RoseTree Int
preLabel = fst . go 0 where
go i (Node _ ts) = (Node i ts', i') where -- first change
(ts', i') = gots (i + 1) ts -- second change
gots i [] = ([], i)
gots i (t:ts) = (t':ts', i'') where
(t', i') = go i t
(ts', i'') = gots i' ts
branch = Node ()
nil = branch []
tree = branch [branch [nil, nil], nil]
preLabel tree == Node 0 [Node 1 [Node 2 [],Node 3 []],Node 4 []]
postLabel tree == Node 4 [Node 2 [Node 0 [],Node 1 []],Node 3 []]
import Control.Monad.State
import Control.Applicative
postLabel' :: RoseTree a -> RoseTree Int
postLabel' = (`evalState` 0) . go where
go (Node _ ts) = do
ts' <- traverse go ts
i <- get <* modify (+1)
pure (Node i ts')
preLabel' :: RoseTree a -> RoseTree Int
preLabel' = (`evalState` 0) . go where
go (Node _ ts) = do
i <- get <* modify (+1)
ts' <- traverse go ts
pure (Node i ts')
postLabel' :: RoseTree a -> RoseTree Int
postLabel' = (`evalState` 0) . go where
go (Node _ ts) =
flip Node <$> traverse go ts <*> (get <* modify (+1))
preLabel' :: RoseTree a -> RoseTree Int
preLabel' = (`evalState` 0) . go where
go (Node _ ts) =
Node <$> (get <* modify (+1)) <*> traverse go ts
|
Is the composition of an arbitrary monad with a traversable always a monad?
Date : March 29 2020, 07:55 AM
hope this fix your issue No, it's not always a monad. You need extra compatibility conditions relating the monad operations of the two monads and the distributive law sequence :: n (m a) -> m (n a), as described for example on Wikipedia. Your previous question gives an example in which the compatibility conditions are not met, namely
|
confusion over the passing of State monad in Haskell
Date : March 29 2020, 07:55 AM
will be helpful for those in need It really boils down to understanding that state is isomorphic to s -> (a, s). So any value "wrapped" in a monadic action is a result of applying a transformation to some state s (a stateful computation producing a). Passing a state between two stateful computations f :: a -> State s b
g :: b -> State s c
f >=> g
\a -> f a >>= g
a -> State s c
m >>= k = StateT $ \ s -> do
~(a, s') <- runStateT m s
runStateT (k a) s'
a >> b
a >>= \_ -> b
tick :: State Int Int
tick = get >>= \n ->
put (n+1) >>
return n
tick = do
n <- get
put (n + 1)
return n
|