2014-08-27 93 views
0

我试图翻译Haskell。遍历抽象语法树

我需要走HsModule结构(由parseModule源返回), HsIdent字符串,其中字符串是一个英文标识符 翻译成HsIdent字符串,其中字符串是一些其他自然语言的标识符(即意大利语,法语,...)。

我不知道是否存在一些直接策略,或许在TH中,走一个HsModule结构(即将一个函数应用于每个HsIdent字符串),而没有显式的展开函数用于所涉及的子结构?

我希望我的要求够清楚,非常感谢您宝贵的援助。

此致敬礼。

回答

0

我在Data.Generics包中找到了解决方案。

HsModule是数据分型的一个实例,因此可享有与通用封装的横动函数来处理它。我选择SYB因为相当好documented

我的解决办法是:

module Main where 

import Data.Generics 
import Language.Haskell.Syntax 
import Language.Haskell.Parser 
import Language.Haskell.Pretty 
import Control.Monad 

translate:: ParseResult HsModule -> Maybe String 
translate r = case r of 
       ParseOk a -> Just (show $ prettyPrint $ translateHsIdent "_italian" a) 
       ParseFailed _ _ -> Nothing 

translateHsIdent :: Data a => String -> a -> a 
translateHsIdent k = everywhere (mkT (addStrangerIdentifier k)) 
    where 
     addStrangerIdentifier :: String -> HsName -> HsName 
     addStrangerIdentifier s (HsIdent i) = HsIdent (i ++ s) 

main = maybe (putStrLn "Parse Error") putStrLn result 
    where 
     result :: Maybe String 
     result = translate $ parseModule "main = putStrLn \"Just a Try\"" 

我希望它可以为别人有用。