1

I'm making a program using Haskell that requires simple save and load functions. When I call the save function, I need to put a string into a text file. When I call load, I need to pull the string out of the text file.

I'm aware of the complexities surrounding IO in Haskell. From some reading around online I have discovered that it is possible through a 'main' function. However, I seem to only be able to implement either save, or load... not both.

For example, I have the following function at the moment for reading from the file.

main = do  
 contents <- readFile "Test.txt"  
 putStrLn contents  

How can I also implement a write function? Does it have to be within the same function? Or can I separate it? Also, is there a way of me being able to name the functions load/save? Having to call 'main' when I actually want to call 'load' or 'save' is rather annoying.

I can't find any examples online of someone implementing both, and any implementations I've found of either always go through a main function.

Any advice will be greatly appreciated.

Will Ness
  • 70,110
  • 9
  • 98
  • 181
SuperHanz98
  • 2,090
  • 2
  • 16
  • 33
  • 2
    That's not a function; it's an IO action. – chepner Apr 24 '19 at 16:33
  • 4
    @chepner Sure, but I don't think that's really a helpful perspective to have for someone who doesn't already know what it means and is struggling to do IO at all. – amalloy Apr 24 '19 at 16:35
  • 1
    "From some reading around online I have discovered that it is possible through a 'main' function." `main` is the *entrypoint* of your program, just like the `public static void main()` function in Java. It's not the only place where you can do IO, you can make as many IO functions as you want and name them whatever you'd like. It's just, if those functions are going to be used, eventually they'll need to be called (directly or indirectly) by `main`. – DarthFennec Apr 24 '19 at 17:48

1 Answers1

4

I'm aware of the complexities surrounding IO in Haskell.

It's actually not that complex. It might seem a little intimidating at first but you'll quickly get the hang of it.

How can I also implement a write function?

The same way

Or can I separate it?

Yes

Also, is there a way of me being able to name the functions load/save?

Yes, for example you could do your loading like this:

load :: IO String
load = readFile "Test.txt"

All Haskell programs start inside main, but they don't have to stay there, so you can use it like this:

main :: IO ()
main = do
  contents <- load -- notice we're using the thing we just defined above
  putStrLn contents

Note the main is always what your program does; But your main doesn't only have to do a single thing. It could just as well do many things, including for instance reading a value and then deciding what to do; Here's a more complicated (complete) example - I expect you'll not understand all parts of it right off the bat, but it at least should give you something to play around with:

data Choice = Save | Load

pickSaveOrLoad :: IO Choice
pickSaveOrLoad = do
   putStr "Do you want to save or load? "
   answer <- getLine
   case answer of
     "save" -> return Save
     "load" -> return Load
     _      -> do
       putStrLn "Invalid choice (must pick 'save' or 'load')"
       pickSaveOrLoad

save :: IO ()
save = do
  putStrLn "You picked save"
  putStrLn "<put your saving stuff here>"

load :: IO ()
load = do
  putStrLn "You picked load"
  putStrLn "<put your loading stuff here>"

main :: IO ()
main = do
  choice <- pickSaveOrLoad
  case choice of
    Save -> save
    Load -> load

Of course it's a bit odd to want to do either save or load, most programs that can do these things want to do both, but I don't know what exactly you're going for so I kept it generic.

Cubic
  • 14,902
  • 5
  • 47
  • 92