Call main function with arguments - haskell

I have problem with reading from file. Whenever I need to read from a file, I do something like this:
main = do x <- readFile "/tmp/foo.txt"
putStr x
But now I would like the path to be an argument, so I tried the following
main s = do x <- readFile s
putStr x
It doesn't work. I see the following error:
Couldn't match expected type `IO t0'
with actual type `FilePath -> IO ()'
In the expression: main
When checking the type of the function `main'
My homework is to write a program and the program has to contain a main function (because it will be compiled) and argument of call must contain the name of the file. I'm not sure I understand this and I don't know how to proceed. I will grateful for some help.

The Haskell report specifies that the main function always has type IO t, (for some type t which will be ignored) and hence never takes normal function arguments, so this is not the right approach.
You are looking for the function getArgs (for which you have to import the module System.Environment. It returns the arguments passed to your program as a list of Strings.
So your code would look like:
import System.Environment
main = do
args <- getArgs
case args of
[file] -> do
x <- readFile file
putStr x
_ -> putStrLn "Wrong number of arguments"

In Haskell, the arguments are NOT given to the main function because of the way Haskell binds its start up and to remain consistent. You need to use System.Environment.getArgs.
In particular, because Haskell is a pure functional language, main is a monadic action that organizes the side-effect-ful computations performed by the software – the result computed by main is discarded, because in functional languages you are detached from the environment w.r.t. computation and only interact with it as a side-effect.
Example
import System.Environment
main = do x <- getArgs; print x
This will print out whatever you type on the command line.
The Haskell wiki has an excellent tutorial on the topic.

Related

Haskell Input to create a String List

I would like to allow a user to build a list from a series of inputs in Haskell.
The getLine function would be called recursively until the stopping case ("Y") is input, at which point the list is returned.
I know the function needs to be in a similar format to below. I am having trouble assigning the correct type signatures - I think I need to include the IO type somewhere.
getList :: [String] -> [String]
getList list = do line <- getLine
if line == "Y"
then return list
else getList (line : list)
So there's a bunch of things that you need to understand. One of them is the IO x type. A value of this type is a computer program that, when later run, will do something and produce a value of type x. So getLine doesn't do anything by itself; it just is a certain sort of program. Same with let p = putStrLn "hello!". I can sequence p into my program multiple times and it will print hello! multiple times, because the IO () is a program, as a value which Haskell happens to be able to talk about and manipulate. If this were TypeScript I would say type IO<x> = { run: () => Promise<x> } and emphatically that type says that the side-effecting action has not been run yet.
So how do we manipulate these values when the value is a program, for example one that fetches the current system time?
The most fundamental way to chain such programs together is to take a program that produces an x (an IO x) and then a Haskell function which takes an x and constructs a program which produces a y (an x -> IO y and combines them together into a resulting program producing a y (an IO y.) This function is called >>= and pronounced "bind". In fact this way is universal, if we add a program which takes any Haskell value of type x and produces a program which does nothing and produces that value (return :: x -> IO x). This allows you to use, for example, the Prelude function fmap f = (>>= return . f) which takes an a -> b and applies it to an IO a to produce an IO b.
So It is so common to say things like getLine >>= \line -> putStrLn (upcase line ++ "!") that we invented do-notation, writing this as
do
line <- getLine
putStrLn (upcase line ++ "!")
Notice that it's the same basic deal; the last line needs to be an IO y for some y.
The last thing you need to know in Haskell is the convention which actually gets these things run. That is that, in your Haskell source code, you are supposed to create an IO () (a program whose value doesn't matter) called Main.main, and the Haskell compiler is supposed to take this program which you described, and give it to you as an executable which you can run whenever you want. As a very special case, the GHCi interpreter will notice if you produce an IO x expression at the top level and will immediately run it for you, but that is very different from how the rest of the language works. For the most part, Haskell says, describe the program and I will give it to you.
Now that you know that Haskell has no magic and the Haskell IO x type just is a static representation of a computer program as a value, rather than something which does side-effecting stuff when you "reduce" it (like it is in other languages), we can turn to your getList. Clearly getList :: IO [String] makes the most sense based on what you said: a program which allows a user to build a list from a series of inputs.
Now to build the internals, you've got the right guess: we've got to start with a getLine and either finish off the list or continue accepting inputs, prepending the line to the list:
getList = do
line <- getLine
if line == 'exit' then return []
else fmap (line:) getList
You've also identified another way to do it, which depends on taking a list of strings and producing a new list:
getList :: IO [String]
getList = fmap reverse (go []) where
go xs = do
x <- getLine
if x == "exit" then return xs
else go (x : xs)
There are probably several other ways to do it.

How to combine a readProcess monad with where in Haskell?

Below script is intended as an extension of a published and working Pandoc Haskell filter script. What has been added is a call to the shell command curl.
#!/usr/bin/env runhaskell
-- svgtex.hs
import Text.Pandoc.JSON
import System.Process
curl latex = readProcess "curl" ["-d", "type=tex&q=" ++ latex, "http://localhost:16000"] ""
main = toJSONFilter svgtex
where svgtex (Math style latex) = do
svg <- curl latex
return (Math style (svg))
svgtex x = x
However, being completely new to Haskell functional programming, it is not surprising that my script fails with:
Couldn't match expected type `IO Inline' with actual type `Inline'
In the expression: x
In an equation for `svgtex': svgtex x = x
In an equation for `main':
...
Despite having skipped over a number on-line Haskell tutorials and StackExchange Q&As, the concept of monads has still not entirely dawned upon me. Hence, a detailed explanation about all things wrong in above script would be very much appreciated!
The problem lies here:
svgtex x = x
The complier complains that
Couldn't match expected type `IO Inline' with actual type `Inline'
because x is an Inline, while svgtex must return an IO Inline. To inject the x into the IO monad, we can simply use the return function
svgtex x = return x
To fully understand what's going on see any monad tutorial (or LYAH). Roughly put, a value of type IO Inline represents an action that can perform any amount of I/O and finally return a value of type Inline. The return function is used to turn a pure value into a dummy IO action which does not do any I/O, but simply return the result.

Why/how does recursive IO work?

Haskell IO is often explained in terms of the entire program being a pure function (main) that returns an IO value (often described as an imperative IO program), which is then executed by the runtime.
This mental model works fine for simple examples, but fell over for me as soon as I saw a recursive main in Learn You A Haskell. For example:
main = do
line <- getLine
putStrLn line
main
Or, if you prefer:
main = getLine >>= putStrLn >> main
Since main never terminates, it never actually returns an IO value, yet the program endlessly reads and echoes back lines just fine - so the simple explanation above doesn't quite work. Am I missing something simple or is there a more complete explanation (or is it 'simply' compiler magic) ?
In this case, main is a value of type IO () rather than a function. You can think of it as a sequence of IO a values:
main = getLine >>= putStrLn >> main
This makes it a recursive value, not unlike infinite lists:
foo = 1 : 2 : foo
We can return a value like this without needing to evaluate the whole thing. In fact, it's a reasonably common idiom.
foo will loop forever if you try to use the whole thing. But that's true of main too: unless you use some external method to break out of it, it will never stop looping! But you can start getting elements out of foo, or executing parts of main, without evaluating all of it.
The value main denotes is an infinite program:
main = do
line <- getLine
putStrLn line
line <- getLine
putStrLn line
line <- getLine
putStrLn line
line <- getLine
putStrLn line
line <- getLine
putStrLn line
line <- getLine
putStrLn line
...
But it's represented in memory as a recursive structure that references itself. That representation is finite, unless someone tries to unfold the entire thing to get a non-recursive representation of the entire program - that would never finish.
But just as you can probably figure out how to start executing the infinite program I wrote above without waiting for me to tell you "all" of it, so can Haskell's runtime system figure out how to execute main without unfolding the recursion up-front.
Haskell's lazy evaluation is actually interleaved with the runtime system's execution of the main IO program, so this works even for a function that returns an IO action which recursively invokes the function, like:
main = foo 1
foo :: Integer -> IO ()
foo x = do
print x
foo (x + 1)
Here foo 1 is not a recursive value (it contains foo 2, not foo 1), but it's still an infinite program. However this works just fine, because the program denoted by foo 1 is only generated lazily on-demand; it can be produced as the runtime system's execution of main goes along.
By default Haskell's laziness means that nothing is evaluated until it's needed, and then only "just enough" to get past the current block. Ultimately the source of all the "need" in "until it's needed" comes from the runtime system needing to know what the next step in the main program is so it can execute it. But it's only ever the next step; the rest of the program after that can remain unevaluated until after the next step has been fully executed. So infininte programs can be executed and do useful work so long as it's always only a finite amount of work to generate "one more step".

Simple haskell code can't compile

I start learning Haskell, and just tried a simple code, and it shows me some errors when I run
doubleMe :: Int -> Int
doubleMe x = x + x
main = do
doubleMe 2
ghc -c first.hs
The errors are:
$ ghc -c first.hs
first.hs:4:1:
Couldn't match expected type IO t0' with actual typeInt'
In the expression: main
When checking the type of the function `main'
While I use GCHi to debug, there were no issues to load doubleMe function first, and call it later. Any help would be appreciated.
Every function in Haskell returns a value of a certain type.
In this case, the doubleMe function returns a value of the Int type. When you load a file from the ghci interpreter, it loads all the functions from the file and makes them available to you.
The main function is a slightly special function, much like in other languages. It defines the entry point of a Haskell program. However, since it is just another Haskell function it too must return a value of a particular type. The main function is constrained to return a value of the IO type, most commonly IO ().
IO itself is quite special too, belonging to a class of types called monads. You can read up on the IO monad here.
Let us now return to your code:
main = do
doubleMe 2
Ignore the do syntax for a moment. You're basically telling the compiler that the main function returns doubleMe 2 which is of type Int. This won't fly. main has to return a value of IO type. In which case, you can use the return function to convert an Int value into an IO Int value. (return functions are functions that all monadic types must have. Very simply put, it converts a value of any type, into a monadic value.)
So this becomes:
main = do
return (doubleMe 2)
This is perfectly valid code, and will compile. However, once you run the program, you'll notice that it doesn't do anything. That's because the program returns the value 4.
In fact, you can write it without the do, and it becomes:
main = return (doubleMe 2)
This will work too.
Let us assume however, that you want to print out the value. This is where IO really comes in. Printing to a screen is an IO action.
main = do
print (doubleMe 2)
return (doubleMe 2)
A do expression allows you to chain a set of IO actions. So your program will still return the value 4 but it will first evaluate the expression print (doubleMe 2). As expected, that actually results in printing the value doubleMe 2.
Examine the print function in ghci.
> :t print
print :: Show a => a -> IO ()
The print function works on a value of any type that can be shown and it results in an IO action (printing to the screen) but returns nothing ().
All of these examples work, and will hopefully make things a little clear. (Look at the type signatures for main).
-- main :: IO Int
main = return (doubleMe 2)
-- main :: IO Int
main = do
print (doubleMe 2)
return (doubleMe 2)
-- main :: IO ()
main = do
print (doubleMe 2)
return ()
-- main :: IO ()
main = do
print (doubleMe 2)
-- main :: IO ()
main = print (doubleMe 2)
-- main :: IO ()
main = do
print "Hello"
print (doubleMe 2)
return ()
-- main :: IO String
main = do
print "Hello"
print (doubleMe 2)
return "Hello"
main must be a value of type IO a, and doubleMe 2 has type Int. You probably wanted to print the value:
main = print (doubleMe 2)
It doesn't work because anything using do notation must return a monad. GHCI does some things to make it more useful but it doesn't exactly work like code compiled by GHC.
print :: Show a => a -> IO ()
print takes a value that is an instance of Show and returns an empty IO action. This is most likely what you want to do.
main = print (doubleMe 2)
Should work as probably what you want to do. You don't have the type of the main function defined but in haskell in has to have the type main :: IO (). Looking at the type of doubleMe you can probably see why your code doesn't work.
Your main function takes nothing and returns an integer. You probably want
doubleMe :: Int -> Int
doubleMe x = x + x
main = do
print $ doubleMe 2
which instead outputs 4 to STDOUT.
Congratulations, you have run into Monads. main is an IO monad and must act as such. IO monads do not return Ints. Instead an IO Monad is an IO action, returned by print and executed at runtime.
There are some things happening behind the scenes that make it hard to understand this error message. Here's the reasoning:
Your file doesn't have a module name, so ghc assumes that you are defining module Main.
The name main in module Main has to have type IO something.
But the main you wrote has type Int.
IO something is not the same as Int, no matter what we choose for the something.
GHC only reports the last step.
If you want to print the Int, you can use print to construct an IO action:
main = do
print (doubleMe 2)
This problem doesn't show up in ghci, because there, you can enter expressions of whatever type you want. If the type is IO something, ghci will execute the IO action for you. (Example: readFile "foo.txt"). If the type is not IO something, ghci will add a call to print and then execute that IO action (Example: ['a' .. 'z']).
In a source file, you have to add the call to print yourself if you want it or need it.

Newbie: understanding main and IO()

While learning Haskell I am wondering when an IO action will be performed. In several places I found descriptions like this:
"What’s special about I/O actions is that if they fall into the main function, they are performed."
But in the following example, 'greet' never returns and therefore nothing should be printed.
import Control.Monad
main = greet
greet = forever $ putStrLn "Hello World!"
Or maybe I should ask: what does it mean to "fall into the main function"?
First of all, main is not a function. It is indeed just a regular value and its type is IO (). The type can be read as: An action that, when performed, produces a value of type ().
Now the run-time system plays the role of an interpreter that performs the actions that you have described. Let's take your program as example:
main = forever (putStrLn "Hello world!")
Notice that I have performed a transformation. That one is valid, since Haskell is a referentially transparent language. The run-time system resolves the forever and finds this:
main = putStrLn "Hello world!" >> MORE1
It doesn't yet know what MORE1 is, but it now knows that it has a composition with one known action, which is executed. After executing it, it resolves the second action, MORE1 and finds:
MORE1 = putStrLn "Hello world!" >> MORE2
Again it executes the first action in that composition and then keeps on resolving.
Of course this is a high level description. The actual code is not an interpreter. But this is a way to picture how a Haskell program gets executed. Let's take another example:
main = forever (getLine >>= putStrLn)
The RTS sees this:
main = forever MORE1
<< resolving forever >>
MORE1 = getLine >>= MORE2
<< executing getLine >>
MORE2 result = putStrLn result >> MORE1
<< executing putStrLn result (where 'result' is the line read)
and starting over >>
When understanding this you understand how an IO String is not "a string with side effects" but rather the description of an action that would produce a string. You also understand why laziness is crucial for Haskell's I/O system to work.
In my opinion the point of the statement "What’s special about I/O actions is that if they fall into the main function, they are performed." is that IO actions are first class citizens. That is, IO-actions can occur at all places where values of other data types like Int can occur. For example, you can define a list that contains IO actions as follows.
actionList = [putStr "Hello", putStr "World"]
The list actionList has type [IO ()]. That is, the list contains actions that interact with the world, for example, print on the console or read in input from the user. But, in defining this list we do not execute the actions, we simply put them in a list for later use.
If an IO can occur somewhere in your program, the question arrises when these actions are performed and here main comes into play. Consider the following definition of main.
main = do
actionList !! 0
actionList !! 1
This main function projects to the first and the second component of the list and "executes" the corresponding actions by using them within its definition. Note that it does not necessarily have to be the main function itself that executes an IO action. Any function that is called from the main function can execute actions as well. For example, we can define a function that calls the actions from actionList and let main call this function as follows.
main = do
caller
putStr "!"
caller = do
actionList !! 0
actionList !! 1
To highlight that it does not have to be a simple renaming like in main = caller I have added an action that prints an exclamation mark after it has performed the actions from the list.
Simple IO actions can be combined into more advanced ones by using do notation.
main = do
printStrLn "Hello"
printStrLn "World"
combines the IO action printStrLn "Hello" with the IO action printStrLn "World". Main is now an IO action first printing a line that says "Hello" and then a line that says "World". Written without do-notation (which is just syntactic suger) it looks like this:
main = printStrLn "Hello" >> printStrLn "World"
Here you can see the >> function combining the two actions.
You can create an IO action that reads a line, passes it to a function(that does awesome stuff to it :)) and the prints the result like this:
main = do
input <- getLine
let result = doAwesomeStuff input
printStrLn result
or without binding the result to a variable:
main = do
input <- getLine
printStrLn (doAwesomeStuff input)
This can ofcourse also be written as IO actions and functions that combine them like this:
main = getLine >>= (\input -> printStrLn (doAwesomeStuff input))
When you run the program the main IO action is executed. This is the only time any IO actions are actually executed. (well technically you can also execute them within you program, but it is not safe. The function that does the is called unsafePerformIO.)
You can read more here: http://www.haskell.org/haskellwiki/Introduction_to_Haskell_IO/Actions
(This link is probably a better explaination than mine, but I only found it after I had written nearly everything. It is also quite a bit longer)
launchAMissile :: IO ()
launchAMissile = do
openASilo
loadCoordinates
launchAMissile
main = do
let launch3missiles = launchAMissile >> launchAMissile >> launchAMissile
putStrLn "Not actually launching any missiles"
forever isn't a loop like C's while (true). It is a function that produces an IO value (which contains an infinitely repeated sequence of actions), which is consumed by the caller. (In this case, the caller is main, which means that the actions get executed by the runtime system).

Resources