I'm trying to learn to use plated to transform and search through the python AST generated by language-python (https://hackage.haskell.org/package/language-python-0.5.4/docs/Language-Python-Common-AST.html)
To briefly summarize the types:
- Modules is a list of statements
- A statement can contain further statements or expressions
- An expression can contain further expressions, identities or operators
I created a hello world to get started with these two libraries. Here's my code that defines plate for a subset of the python AST types:
{-# LANGUAGE FlexibleInstances#-}
module Lib
( someFunc
) where
import Language.Python.Version3.Parser
import Language.Python.Common.Token
import Language.Python.Common.AST
import Language.Python.Common.SrcLocation
import Control.Lens.Plated
import Data.Data.Lens
import Language.Python.Common.Pretty
import Language.Python.Common.PrettyAST
instance Plated (Statement SrcSpan) where
plate = uniplate
instance Plated (Expr SrcSpan) where
plate = uniplate
instance Plated (Ident SrcSpan) where
plate = uniplate
instance Plated (Op SrcSpan) where
plate = uniplate
extract (Right (x, _)) = x
someFunc :: IO ()
someFunc = do
putStrLn $ show $ concatMap (map prettyText) $ universe $ extract $ parseStmt "2*(1+x)" "file.py"
putStrLn $ show $ map prettyText $ universe $ extract $ parseExpr "2*(1+x)" "file.py"
The output of this program is
["2 * (1 + x)"]
["2 * (1 + x)","2","(1 + x)","1 + x","1","x"]
The problem I'm seeing is that plated only sees the type consistent with the root node. If I start with a statement as my root node it doesn't look at expressions which are children of the statement. In the second case where I look at expressions it seems to descend and find child expressions. But, it's not showing me the operators or identity types that are children of expressions.
How do get plate to descend into a data structure with mixed types? Or am I using the wrong tool for this?