NOTE: ADT 風格 AST 標記位置訊息技巧
1. 定義
data Term = TmPos Position Term | -- 剩餘的 term constructor
對應的 error report monad
report : String -> Either (String, Maybe Position) a report s = Left (s, Nothing) addPos : Position -> Either (String, Maybe Position) a -> Either (String, Maybe Position) a addPos pos (Left (msg, Nothing)) = Left (msg, Just pos) addPos _ ma = ma
2. 用途
這個方法真正的巧妙之處在於,任何時候要讓 report monad 擁有 position 資訊都可以,也不會被其他人覆蓋掉。
在解析文字建構 term
的時候,也可以在任何程式裡加上位置資訊又不需要去修改本來的定義。假設
Parser a
是解析文字之後得出 a
的解析器 monad
簽名;那麼下列定義就可以為任何 Parser a
重新建構一個具有 Position
版本的 a
withPos : (Position -> a -> a) -> Parser a -> Parser a withPos f p = f <$> getPosition <*> p
用上面的 Term
定義舉例,就會像是
withPos TmPos parseXxx
只要上面 parseXxx
是 Parser Term
即可。