如何找出可以在表达式上运行的函数?

时间:2017-04-30 10:50:23

标签: haskell

我希望以编程方式找出模块中哪些函数可能适用于特定表达式。

让我们具体化。

{-# 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;关于如何将表达式作为参数传递给这些函数,然后检查这些表达式是否会进行类型检查,我们就失去了作用。

如果我可以这样做,我可以在模块中的所有函数中运行过滤器,这可以让我找出适用的函数。

非常感谢提前。

1 个答案:

答案 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