Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using content of a string to call function with same name

Tags:

haskell

eval

I have a main like the following:

main :: IO ()
main = do
  args <- getArgs
  putStrLn $ functionName args
  where 
    functionName args = "problem" ++ (filter (/= '"') $ show (args!!0))

Instead of putting the name to stdout like I do it right now, I want to call the function.

I am aware of the fact, that I could use hint (as mentioned in Haskell: how to evaluate a String like "1+2") but I think that would be pretty overkill for just getting that simple function name.

At the current stage it does not matter if the program crashes if the function does not exist!

like image 632
NobbZ Avatar asked Dec 09 '22 10:12

NobbZ


2 Answers

Without taking special measures to preserve them, the names of functions will likely be gone completely in a compiled Haskell program.

I would suggest just making a big top-level map:

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))
like image 60
GS - Apologise to Monica Avatar answered Feb 16 '23 21:02

GS - Apologise to Monica


If you're going to do this, you have a few approaches, but the easiest by far is to just pattern match on it

This method requires that all of your functions you want to call have the same type signature:

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

This requires you to add a line to runFunc each time you add a new problemN, but that's pretty manageable.

like image 26
bheklilr Avatar answered Feb 16 '23 21:02

bheklilr