Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 使用字符串内容调用同名函数_Haskell_Eval - Fatal编程技术网

Haskell 使用字符串内容调用同名函数

Haskell 使用字符串内容调用同名函数,haskell,eval,Haskell,Eval,我有一个主要的问题,如下所示: main::IO() main=do args如果不采取特殊措施来保存它们,函数名很可能会完全消失在已编译的Haskell程序中 我建议只制作一张大的顶级地图: import Data.Map ( Map ) import qualified Data.Map as Map functions :: Map String (IO ()) functions = Map.fromList [("problem1", problem1), ...] call ::

我有一个主要的问题,如下所示:

main::IO()
main=do

args如果不采取特殊措施来保存它们,函数名很可能会完全消失在已编译的Haskell程序中

我建议只制作一张大的顶级地图:

import Data.Map ( Map )
import qualified Data.Map as Map

functions :: Map String (IO ())
functions = Map.fromList [("problem1", problem1), ...]

call :: String -> IO ()
call name =
    case Map.lookup name of
        Nothing -> fail $ name + " not found"
        Just m -> m

main :: IO ()
main = do
  args <- getArgs
  call $ functionName args
  where 
    functionName args = "problem" ++ (filter (/= '"') $ show (args!!0))
导入数据.Map(Map)
导入符合条件的数据。映射为映射
函数::映射字符串(IO())
函数=Map.fromList[(“问题1”,问题1),…]
调用::字符串->IO()
称呼=
case Map.lookup的名称
Nothing->fail$name+“未找到”
只是m->m
main::IO()
main=do

args如果要这样做,有几种方法,但最简单的方法是在上面进行模式匹配

此方法要求要调用的所有函数都具有相同的类型签名:

problem1 :: Int
problem1 = 1

problem2 :: Int
problem2 = 2

runFunc :: String -> Maybe Int
runFunc "problem1" = Just problem1
runFunc "problem2" = Just problem2
runFunc _ = Nothing

main = do
    args <- getArgs
    putStrLn $ runFunc $ functionName args
问题1::Int
问题1=1
问题2::Int
问题2=2
runFunc::String->Maybe Int
runFunc“problem1”=仅问题1
runFunc“problem2”=仅问题2
runFunc=无
main=do

args如果没有奇特的非标准特性,就无法获得标识符的字符串表示,因为编译后不会保留这些信息。因此,您必须将这些函数名作为字符串常量写在某处

如果函数定义都在一个文件中,我建议使用数据类型和lambda,以避免完全复制这些函数名:

Data Problem = {
    problemName :: String,
    evalProblem :: IO () # Or whatever your problem function signatures are
    }

problems = [Problem]
problems = [
    Problem {
        problemName = "problem1",
        evalProblem = do ... # Insert code here
        },
    Problem
        problemName = "problem2",
        evalProblem = do ... # Insert code here
        }
    ]

main :: IO ()
main = do
    args <- getArgs
    case find (\x -> problemName x == (args!!0)) problems of
        Just x -> evalProblem x
        Nothing -> # Handle error
数据问题={
problemName::String,
evalProblem::IO()#或任何您的问题函数签名
}
问题=[问题]
问题=[
问题{
problemName=“problem1”,
evalProblem=do…#在此处插入代码
},
问题
problemName=“problem2”,
evalProblem=do…#在此处插入代码
}
]
main::IO()
main=do
args problemName x==(args!!0))的问题
仅x->评估问题x
Nothing->#处理错误

Edit:我想澄清一下,这里重要的一点是您有一个。

您不能以这种方式将字符串提升到可执行表达式中。唯一的方法是解释或编译字符串,这两种方法都要求您指定导入,以将所需的函数(潜在目标)引入范围。您提到了提示,还有一些人提到了模板Haskell,但是,除了解析用户输入和从白名单中选择函数之外,还有一点安全问题;允许用户运行任意代码的程序不容易保护。是的,这种安全性让我选择了@trolox建议的类似方法。在这个数据结构中,我现在有了这个函数,它的id和一个标题,我现在也在main中打印出来了。因此,我不必让函数本身成为IO…我很惊讶你没有推出TemplateHaskell解决方案!不总是初学者友好,但它可以自动刮取模块并构造
问题
变量。当你不知道为什么这个问题需要解决时,这很困难。当我觉得这是一个临时措施或是一个糟糕的设计选择时,我会犹豫是否推荐一个更健壮的解决方案。