Haskell: Need Enlightenment with Calculator program

心已入冬 提交于 2019-12-10 20:17:31

问题


I have an assignment which is to create a calculator program in Haskell. For example, users will be able to use the calculator by command lines like:

>var cola =5; //define a random variable
>cola*2+1;
(print 11)
>var pepsi = 10 
>coca > pepsi;
(print false)
>def coke(x,y) = x+y;  //define a random function
>coke(cola,pepsi);
(print 15)

//and actually it's more complicated than above

I have no clue how to program this in Haskell. All I can think of right now is to read the command line as a String, parse it into an array of tokens. Maybe go through the array, detect keywords such "var", "def" then call functions var, def which store variables/functions in a List or something like that. But then how do I store data so that I can use them later in my computation?

Also am I on the right track because I am actually very confused what to do next? :(

*In addition, I am not allowed to use Parsec!*


回答1:


It looks like you have two distinct kinds of input: declarations (creating new variables and functions) and expressions (calculating things).

You should first define some data structures so you can work out what sort of things you are going to be dealing with. Something like:

data Command = Define Definition | Calculate Expression | Quit
type Name = String
data Definition = DefVar Name Expression | DefFunc Name [Name] Expression
-- ^ alternatively, implement variables as zero-argument functions
-- and merge these cases
data Expression = Var Name | Add Expression Expression | -- ... other stuff
type Environment = [Definition]

To start off with, just parse (tokenise and then parse the tokens, perhaps) the stuff into a Command, and then decide what to do with it.

Expressions are comparatively easy. You assume you already have all the definitions you need (an Environment) and then just look up any variables or do additions or whatever.

Definitions are a bit trickier. Once you've decided what new definition to make, you need to add it to the environment. How exactly you do this depends on how exactly you iterate through the lines, but you'll need to pass the new environment back from the interpreter to the thing which fetches the next line and runs the interpreter on it. Something like:

main :: IO ()
main = mainLoop emptyEnv
 where
  emptyEnv = []

mainLoop :: Environment -> IO ()
mainLoop env = do
  str <- getLine
  case parseCommnad str of
    Nothing -> do
      putStrLn "parse failed!"
      mainLoop env
    Just Quit -> do
      return ()
    Just (Define d) -> do
      mainLoop (d : env)
    Just (Calculate e) -> do
      putStrLn (calc env e)
      mainLoop env

-- the real meat:
parseCommand :: String -> Maybe Command
calc :: Environment -> Expression -> String -- or Integer or some other appropriate type

calc will need to look stuff up in the environment you create as you go along, so you'll probably also need a function for finding which Definition corresponds to a given Name (or complaining that there isn't one).

Some other decisions you should make:

  • What do I do when someone tries to redefine a variable?
  • What if I used one of those variables in the definition of a function? Do I evaluate a function definition when it is created or when it is used?

These questions may affect the design of the above program, but I'll leave it up to you to work out how.




回答2:


First, you can learn a lot from this tutorial for haskell programming

You need to write your function in another doc with .hs
And you can load the file from you compiler and use all the function you create
For example

plus :: Int -> Int  -- that mean the function just work with a number of type int and return Int
plus x y = x + y    -- they receive x and y and do the operation 


来源:https://stackoverflow.com/questions/15046196/haskell-need-enlightenment-with-calculator-program

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!