Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve rewriteM docs #1053

Open
deemp opened this issue Dec 29, 2023 · 0 comments
Open

Improve rewriteM docs #1053

deemp opened this issue Dec 29, 2023 · 0 comments
Labels

Comments

@deemp
Copy link

deemp commented Dec 29, 2023

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])]
@deemp deemp changed the title rewriteM hangs indefinitely Improve rewriteM docs Dec 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants