How to call multiple functions within the code in haskell - haskell

I would like to call multiple functions from within the code, meaning that by executing the .hs file, all functions named will be executed.
I tried using main with putStrLn, but this is rather complicated and doesn't seem to work.
main = do
putStrLn (myFunction para1 para2)
putStrLn (anotherFunction para1 para2)
This shows the idea, but it obviosly doesn't work. Escpecially because myFunction returns an Integer and not a char.
I hope someone can help. Thank you in advance.
using "print" solved this problem. Thank you.

Escpecially because myFunction returns an Integer and not a char.
You can use print to print things other than strings. print is equivalent to putStrLn . show, so it can print any type that's showable, which Integer is.

Related

Can I have separate functions for reading and writing to a txt file in Haskell, without using a 'main' function?

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.
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.

Using "printf" on a list in Haskell

How can i use printf over a list?
I have a list of numbers and i want to print them all by respecting a format (ex: %.3f). I tried to use map over printf, but it does not work. So, i have no idea. Can somebody help me with this? Any ideas are acceptable. Is there a way to create a string from a list respecting a custom format?
printf can produce strings instead of just printing them to stdout. This
is because it is overloaded on its result type (it's also part of machinery
that makes it variadic).
import Text.Printf
main :: IO ()
main = putStrLn . unwords $ printf "%.3f" <$> ([1..10] :: [Double])
That should do the trick.
BTW, printf is not type safe and can blow at run time. I recommend you use
something like
formatting.

Compiling / testing Haskell without a main function

I'm working on an assignment in Haskell. However, the base code I am working with does not have a main function defined, and from the wording of the assignment I believe I am not expected to have to write any code outside of the solution to the problem. However, when I try to compile my code, I receive the error:
The IO function 'main' is not defined in module 'Main'
I assume this is because the function does not have a main function. However, when I try to write my own main function:
main :: IO ()
main = solve easy // easy is an array
I get the error:
Couldn't match expected type 'IO()' with actual type '[Int]'
The solve function's type is declared as follows:
solve :: [Int] -> [Int]
So it takes an array and returns an array. What am I doing wrong in writing my main function? Even when I try changing the declaration of main to things like:
main :: [Int]
or
main :: IO [Int]
I still can't get it to compile.
Without writing a proper main with a correct type, as described by #G Philip, you can load your file in ghci by writing ghci file.hs in your terminal, or by invoking :l file.hs inside ghci.
Firstly: the function main must have type IO t for some type t. When the program is executed, the computation defined by main is executed, and its result (of type t) is thrown away; see here.
So, in particular, you cannot have the type of main as [Int] and have the compiler not complain.
Depending on whether you want to see the results of solving the easy case or not, you can try one of the following:
If you want to see the results: print them!
main :: IO ()
main = putStrLn $ show (solve easy)
If you are not interested in seeing the results, throw them away:
main :: IO ()
main = let solution = solve easy
in putStrLn ""
Edit: Note, however, that if you do the latter, then (as #yatima2975 mentions in a comment) the "solve easy" part will not be evaluated.
Just to add to the other answers:
you don't need to write a main function and can still compile the file into a lib and the easiest way to do this is just giving a module name (that is not Main):
module MyCode where
solve :: ...
But of course compiling it might not make any sense anymore (as you will not be able to run it - and of course even if you have not specified what to output anyway).
So in this case rather load the file into ghci:
ghci MyFile.hs
and then everytime you changed something in your code you can do :r inside ghci to reload it.
Or even better set up your favorite editor (emacs and vi are quite easy but sublime text and some other works great too) to give you integrated ghci - this explains what you need to do to setup emacs with haskell-mode if you are interested.
Consider
main :: IO ()
main = do
let res = solve easy // easy is an array
return ()
where return () yields a result of type Unit which conveys with the type signature of main. Note solve easy is bound to res which is not used further.

Error with functions inside tuples in Haskell

i'm playing a little with Haskell and i'm stuck with this error, using the snd function with a tuple (String, list).
snd ("Felix Felices",[("Escarabajos Machacados",52,[f1,f2]),("Ojo de Tigre Sucio",2,[f2])])
ERROR - Cannot find "show" function for:
*** Expression : snd ("Felix Felices",[("Escarabajos Machacados",52,[f1,f2]),("Ojo de Tigre Sucio",2,[f2])])
*** Of type : [([Char],Integer,[(Integer,Integer,Integer) -> (Integer,Integer,Integer)])]
The thing is, if i remove f1, f2 and f3 (they are functions) the code works just fine, it returns the list. Why is this happening, why can't i just put a function inside the tuple's second position?
You can put functions into tuples. But you can't display them - ghci wants to show the result and print it. How should it show (convert to string) the functions? It can't, or at least nobody felt like choosing one way of doing it (which would propably be flawed anyway - at least I can't think of any approach that doesn't have holes to huge even I can see them). Therefore, you can't evaluate something that returns functions or collections of functions in ghci.
The problem isn't really the functions f1 f2 or f3, the problem is that you are trying to print these functions, but functions don't have an instance of Show, so they cannot be printed. However if you try:
Prelude> snd ("Felix Felices",[("Escarabajos Machacados",52,["f1","f2"]),("Ojo de Tigre Sucio",2,["f2"])])
you get the result:
[("Escarabajos Machacados",52,["f1","f2"]),("Ojo de Tigre Sucio",2,["f2"])]
So the problem isn't that you cannot have a function in a tuple, the problem is that you cannot convert functions to strings so they can be printed.
module Text.Show.Functions provides an instance Show (a -> b).
ghci> :m +Text.Show.Functions
ghci> [(*), (/)]
[<function>,<function>]
It's not useful for actually figuring out what the functions are, but there's no good way to do that anyway (well, the debugger and vacuum aside). But if you just want some Show instances for convenience, this is in the standard library.
You cannot print bare functions in Haskell as there is no "show" function defined for them.
You get the same type of error, if you type
Hugs> sqrt
for example
The system tells the type of the expression, which in your case is ([Char],Integer,[(Integer,Integer,Integer) -> (Integer,Integer,Integer)])], but cannot print it, because it is a function.

Haskell -- "The last statement in a 'do' construct must be an expression"

Like it says in the title: What does The last statement in a 'do' construct must be an expression mean? I ended my do block with a putStrLn like it shows in several examples I've seen, and i get an error.
Code:
main = do args <- getArgs
file <-readFile "TWL06.txt"
putStrLn results
Most of the time, it's because your code is mis-aligned and compiler assumes that your "do" block ended prematurely (or has extra code that dont really belong there)
Your last line isn't something like someVar <- putStrLn "hello", by any chance, is it? You'll get that error if you try to do a variable binding on the last line, because it's equivalent to putStrLn "Hello" >>= \someVar -> — it expects there to be an expression at the end.
Incorrect indentation can lead to this error. Also, is good not to use tabs, only spaces.

Resources