하스켈 표현식을 감안할 때, 나는 알파 변환을 수행하고 싶습니다. 일부 비어 있지 않은 변수의 이름을 바꿉니다.하스켈 식으로의 알파 변환
haskell-src-exts Exp 트리에서 작동하는 내 자신의 기능을 구현하기 시작했습니다. 그러나 놀라 울 정도로 치명적이지는 않지만 궁금증을 풀 수 없습니다. 이런 종류의 소스 변환을위한 사용하기 쉬운 라이브러리 솔루션? 이상적으로는 haskell-src-exts와 통합되어야합니다.
하스켈 표현식을 감안할 때, 나는 알파 변환을 수행하고 싶습니다. 일부 비어 있지 않은 변수의 이름을 바꿉니다.하스켈 식으로의 알파 변환
haskell-src-exts Exp 트리에서 작동하는 내 자신의 기능을 구현하기 시작했습니다. 그러나 놀라 울 정도로 치명적이지는 않지만 궁금증을 풀 수 없습니다. 이런 종류의 소스 변환을위한 사용하기 쉬운 라이브러리 솔루션? 이상적으로는 haskell-src-exts와 통합되어야합니다.
"일반 게시판 스크랩"스타일의 제네릭 라이브러리가 빛나는 문제 중 하나입니다!
제가 가장 익숙한 사람은 the uniplate
package입니다. 그러나 실제로는 설치하지 않았으므로 the lens
package에있는 (매우 유사한) 기능을 사용하겠습니다. 여기서 아이디어는 Data.Data.Data
(가장 적합한 수식 이름 임) 및 관련 클래스를 사용하여 다형성 방식으로 일반 작업을 수행한다는 것입니다.
alphaConvert :: Module -> Module
alphaConvert = template %~ changeName
changeName :: Name -> Name
changeName (Ident n) = Ident $ n ++ "_conv"
changeName n = n
(%~)
연산자 lens
내지 단지 일반 순회 template
의해 선택된 모든 행 changeName
함수를 적용하는 것을 의미한다 :
여기서 가장 간단한 예이다. 그래서 이것은 모든 영숫자 식별자를 찾아서 그것에 _conv
을 붙이는 것입니다. 이 식별자 외부 범위에 정의 된 (예 : 수입 된 것으로) 로컬 바인딩과 구분하지 않기 때문에
module AlphaConv where
import Language.Haskell.Exts
import Control.Lens
import Control.Lens.Plated
import Data.Data.Lens
instance Plated_conv Module_conv
main_conv
= do ParseOk_conv md_conv <- parseFile_conv "AlphaConv.hs"
putStrLn_conv $ prettyPrint_conv md_conv
let md'_conv = alphaConvert_conv md_conv
putStrLn_conv $ prettyPrint_conv md'_conv
alphaConvert_conv :: Module_conv -> Module_conv
alphaConvert_conv = template_conv %~ changeName_conv
changeName_conv :: Name_conv -> Name_conv
changeName_conv (Ident_conv n_conv)
= Ident_conv $ n_conv ++ "_conv"
changeName_conv n_conv = n_conv
정말 유용하지,하지만 기본적인 아이디어를 보여줍니다 자체 소스에서이 프로그램을 실행하면이 생산 .
lens
약간 위협적으로 보일 수 있습니다 (이 기능보다 훨씬 많은 기능이 있음). uniplate
또는 다른 라이브러리를 더 쉽게 찾을 수 있습니다.
실제 문제에 접근하는 방법은 내부적으로 알파로 변환 할 하위 표현식을 먼저 선택한 다음 변환을 사용하여 변경하려는 이름을 수정하는 다중 부분 변환입니다.
제네릭이 가능한 한 가지 문제 (AST 사용)는 해결하지만 다른 것은 아니며 (알파 등가물, 회피 등). 나는이 문제를 후자에 대해 더 많은 것으로 해석했다.이 라이브러리에는 몇 가지 라이브러리 ('언 바운드','바인딩')가 있지만'haskell-src-exts'에 쉽게 적용 할 수 있는지 모르겠습니다. –
+1 멋진 글에 대한, 그러나, 나는 이것이 내가 무엇을 찾고 있는지 확실하지 않습니다. 나는 당신이 언급 한 라이브러리에 익숙하지 않지만, 필자가 피하려고하는 것은 그렇게 많은 상용구가 아니라 진정한 논리이다. – xcvii
[bound] (https://github.com/ekmett/bound/) 라이브러리가 ekmett에게 도움이 될 수 있습니다. –