Improve `rewriteM` docs
Opened this issue · 0 comments
deemp commented
Hi! I suggest to improve the docs of rewriteM.
Namely, rewrite:
Rewrite by applying a monadic rule everywhere you can.
Ensures that the rule cannot be applied anywhere in the result.
+ When you want to apply the rule to a result, wrap the result in `Just`.
+ Otherwise, return `Nothing`.
The text below is for context.
The working example may be included into docs.
Goal
The goal is to insert Bottom
with a counter into each Object
binding that doesn't contain a Bottom
.
Attempt 1
This example hangs indefinitely.
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE LambdaCase #-}
module Language.EO.Phi.Ex where
import Control.Lens (Plated, rewriteM, (+=))
import Control.Monad.State (evalState, get)
import Data.Data (Data)
newtype Object = Object [Binding] deriving (Data, Show)
data Binding = Binding Object | Bottom Int deriving (Data, Show)
instance Plated Object
instance Plated Binding
ex1 :: Object
ex1 =
evalState
( rewriteM
( \x@(Object bindings) -> do
cnt <- get
id += 1
let isBottom = \case Bottom _ -> True; _ -> False
pure
$ Just
( if not (any isBottom bindings)
then Object (Bottom cnt : bindings)
else x
)
)
(Object [Binding (Object [])])
)
3
-- >>> ex1
-- ProgressCancelledException
Attempt 2
This example works well.
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE LambdaCase #-}
module Language.EO.Phi.Ex where
import Control.Lens (Plated, rewriteM, (+=))
import Control.Monad.State (evalState, get)
import Data.Data (Data)
newtype Object = Object [Binding] deriving (Data, Show)
data Binding = Binding Object | Bottom Int deriving (Data, Show)
instance Plated Object
instance Plated Binding
ex1 :: Object
ex1 =
evalState
( rewriteM
( \(Object bindings) -> do
let isBottom = \case Bottom _ -> True; _ -> False
if not (any isBottom bindings)
then do
cnt <- get
id += 1
pure $ Just (Object (Bottom cnt : bindings))
else pure Nothing
)
(Object [Binding (Object [])])
)
3
-- >>> ex1
-- Object [Bottom 4,Binding (Object [Bottom 3])]