我希望以编程方式找出模块中哪些函数可能适用于特定表达式。
让我们具体化。
{-# LANGUAGE TemplateHaskell #-}
module Test where
-- we'll import template-haskell from Lens
-- so we can create prisms automatically for our 'AST'
import qualified Control.Lens.TH as LTH
--- some 'AST' in a toy language
data CExp
= CLit Int -- a literal integer
| CAdd CExp CExp -- addition
| CMul CExp CExp -- multiplication
| CSub CExp CExp -- subtraction
deriving Show
-- an eval for our AST
eval :: CExp -> Int
eval exp =
case exp of
CLit i -> i
CAdd e1 e2 ->
eval e1 + eval e2
CMul e1 e2 ->
eval e1 * eval e2
CSub e1 e2 ->
eval e1 - eval e2
-- a function to build a sum using add with our AST, from a list of Int values
listToSums :: [Int] -> CExp
listToSums =
foldr CAdd (CLit 0) . fmap CLit
-- here we make prisms for looking at particular values
-- in the CExp AST
LTH.makePrisms ''CExp
-- let's have an expression:
theList1 :: CExp
theList1 = listToSums [1..38]
现在,在这一点上,我想要一个函数,它可以给我一个特定模块(包括这个)的所有顶级函数的列表,这些函数能够应用于表达式{{1 }}。这将包括使用theList1
创建的棱镜。
如果它使用提示库的makePrisms
monad会很好。我已经尝试了一下,虽然我可以在任何模块的顶层获得所有定义的列表,但我也能找到它们的类型(或多或少),我&# 39;关于如何将表达式作为参数传递给这些函数,然后检查这些表达式是否会进行类型检查,我们就失去了作用。
如果我可以这样做,我可以在模块中的所有函数中运行过滤器,这可以让我找出适用的函数。
非常感谢提前。
答案 0 :(得分:0)
Hint有一个名为typeChecks :: MonadInterpreter m => String -> m Bool
的函数,它告诉你字符串中的表达式是否在解释器的上下文中输入得很好。
fnsAccepting :: MonadInterpreter m => String -> m [Id]
fnsAccepting expr = do
moduleContents <- getLoadedModules >>= traverse getModuleExports
let importedFns = [fn | exports <- moduleContents, Fun fn <- exports]
filterM (\fn -> typeChecks $ fn ++ " " ++ parens expr) importedFns