Error with module main - haskell

Hello I'm doing a program with haskell and need do something like that:
expo :: String -> String
expo "stuff" = " Doing something "
main = do
expo "stuff"
but when I try to run this, this happend:
Couldn't match expected type `IO t0' with actual type `String'
In the expression: main
When checking the type of the function `main'
Some one who can explain me ? ....

What do you want to happen to the return value of expo "stuff"?
Let's assume you want to print it to the console:
main = do
putStrLn $ expo "Stuff"
All statements in a do block need to be of type IO something (see also let bindings) the last must be IO (). If this doesn't make sense to you then you have run into one of haskell's famous learning curves. Read a few more pages in the tutorials and it will become clear with practice. Keep Learning!

Related

Why does the Maybe return type make this crash?

I'm restricting myself the use of prebuilt-in functions for training purposes. I have recoded length as count and it works.
I have a search funtion that simply returns a value at index in a list when given an index and a list. It works completly fine. It throws an error when the index is too large.
search [] _ = error "index too large"
search (a:_) 0 = a
search (_:a) b = search a (b - 1)
Now, I want a safeSearch function that return Nothing if the index is too large of if the list is empty. So I've simply done this.
safeSearch :: [a] -> Int -> Maybe a
safeSearch a b
| b < 0 || b >= count a = Nothing
| otherwise = Just (search a b)
And it works! ... as long as you don't try it on an empty list. Even with an index too large for the list length.
main = print(safeSearch [] 5)
This crashes and I really can't find any way around it.
Even though I don't think my second line is usefull (because if the list is empty, its count is 0 so we drop in the first guard and it should return Nothing?) its not working. Removing it does not solve the problem.
Here's the compile-time error.
main.hs:91:8: error:
* Ambiguous type variable `a0' arising from a use of `print'
prevents the constraint `(Show a0)' from being solved.
Probable fix: use a type annotation to specify what `a0' should be.
These potential instances exist:
instance Show Ordering -- Defined in `GHC.Show'
instance Show Integer -- Defined in `GHC.Show'
instance Show a => Show (Maybe a) -- Defined in `GHC.Show'
...plus 22 others
...plus 13 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
* In the expression: print (safeSearch [] 5)
In an equation for `main': main = print (safeSearch [] 5)
|
91 | main = print(safeSearch [] 5)
| ^^^^^^^^^^^^^^^^^^^^^^
exit status 1
Any idea? Something I'm missing or even completly going wrong? A concept I need to understand deeper?
The problem is a compile error. That means it isn't actually running your code and hitting your error "index too large" call; the compiler is rejecting your code before it can even try to run it. So you're looking in the wrong place if you're trying to change the code to avoid that.
What's actually happening is that safeSearch [] 5 is returning a value of type Maybe a, where a is the type of the elements in the list. But you didn't include any elements in the list, so there is nothing at all to decide what that type a is.
Your function safeSearch can work for any type, so that's actually fine. But you also try to print the Maybe a value. Using print requires a Show instance, and the instance for Maybe a requires there to also be a Show instance for a. Because there is nothing saying what type a is, the compiler has no way of finding the appropriate Show instance for it, so it has to abort compilation with an error.
The most straightforward way to solve it is to add a type annotation (either of the list, or the Maybe a value resulting from safeSearch). Something like this:
main = print (safeSearch ([] :: [Int]) 5)
(This is what the error message is talking about when it says an ambiguous type variable is preventing a Show constraint from being solved, and that the probable fix is to add a type annotation)
Note that this sort of issue is rarely a problem in "real" code. Normally if you have a list processed into another structure with a related type, you will have other code that does something with the elements or the result, or that produced the list (which isn't always empty). You wouldn't normally write a program that does nothing but process an always-empty list and print the result, except for these kinds of quick tests. So normally, when there is that other code as well, there will be enough context for the compiler to deduce the type of your empty list, and the extra type annotations will not be needed. So this kind of extra type annotation is not usually considered a serious burden that needs to be avoided, because they are hardly ever needed in "real" code. You just code as you want, and on the occassion that a compile error makes your realise you need an annotation you simply add it and move on.
If you do this kind of quick check in GHCi rather than writing a full program with a main function, then you also would not have needed the extra type annotation. This is because GHCi has the ExtendedDefaultRules language extension turned on by default. The "default rules" are conditions when GHC will choose a type for you instead of throwing an "ambiguous type" error. The normal default rules are pretty strict, and really only designed for defaulting numeric constraints (like Num a or Real a, etc). They do not apply to your original example. The "extended default rules" apply more often to avoid needing lots of type signatures in the interactive interpreter (since there you enter one line at a time, instead of the compiler being able to see the full module to infer types from usage). In this case entering print (safeSearch [] 5) at the interpreter prompt will work because it defaults the returned type to Maybe (), and it just so happens that printing Nothing :: Maybe () produces the same output as it would if it had correctly guessed the type you actually meant.
But in almost any real program, defaulting a type variable to () will be a stupid thing to do that makes things work less, so I do not recommend getting into the habit of enabling ExtendedDefaultRules in an actual module. Just add the type annotation, or do quick checks in the interpreter instead of in a module.
What you've written works great for any real-world use case. It only fails when someone writes print (safeSearch [] x) - a literal empty list, with no context to tell what result type is expected. It works fine if they pass in a nonempty list, or a list expression that happens to evaluate to an empty list, or if they use the result in a way that lets type inference figure out what was intended.
Further, there is really no way to write the function so that it works when passed a contextless empty list. The burden to make the types clear is necessarily placed on call sites, not the definition. The comments on your question have already shown how to do this; you only have to be that explicit when you're calling your function in a way that's obviously useless.

How to introspect an Haskell file to get the types of its definitions

I have many files that must be processed automatically. Each file holds the response of one student to an exercise which asks the student to give definitions for some functions given a type for each function.
My idea is to have an Haskell script that loads each student file, and verifies if each function has the expected type.
A constraint is that the student files are not defined as modules.
How can I do this?
My best alternative so far is to spawn a GHCi process that will read stdin from a "test file" with GHCi commands, for example:
:load student1.hs
:t g
... and so on ...
then parse the returned output from GHCi to find the types of the functions in the student file.
Is there another clean way to load an arbitrary Haskell file and introspect its code?
Thanks
Haskell does not save type information at runtime. In Haskell, types are used for pre-runtime type checking at the static analysis phase and are later erased. You can read more about Haskell's type system here.
Is there a reason you want to know the type of a function at runtime? maybe we can help with the problem itself :)
Edit based on your 2nd edit:
I don't have a good solution for you, but here is one idea that might work:
Run a script that for each student module will:
Take the name of the module and produce a file Test.hs:
module Test where
import [module-name]
test :: a -> b -> [(b,a)]
test = g
run ghc -fno-code Test.hs
check the output does not contain type errors
write results into a log file
I think if you have a dynamically determined number of .hs files, which you need to load, parse and introspect, you could/should use the GHC API instead.
See for example:
Using GHC API to compile Haskell sources to CORE and CORE to binary
https://mail.haskell.org/pipermail/haskell-cafe/2009-April/060705.html
These might not be something you can use directly — and I haven't done anything like this myself so far either — but these should get you started.
See also:
https://wiki.haskell.org/GHC/As_a_library
https://hackage.haskell.org/package/hint
The closest Haskell feature to that is Data.Typeable.typeOf. Here's a GHCi session:
> import Data.Typeable
> typeOf (undefined :: Int -> Char)
Int -> Char
> typeOf (undefined :: Int -> [Char])
Int -> [Char]
> typeOf (undefined :: Int -> Maybe [Char])
Int -> Maybe [Char]
> :t typeOf
typeOf :: Typeable a => a -> TypeRep
Under the hood, the Typeable a constraint forces Haskell to retain some type tags until runtime, so that they can be retrieved by typeOf. Normally, no such tags exist at runtime. The TypeRep type above is the type for such tags.
That being said, having such information is almost never needed in Haskell. If you are using typeOf to implement something, you are likely doing it wrong.
If you are using that to defer type checks to run time, when they could have been performed at compile time, e.g. using a Dynamic-like type for everything, then you are definitely doing it wrong.
If the function is supposed to be exported with a specific name, I think probably the easiest way would be to just write a test script that calls the functions and checks they return the right results. If the test script doesn't compile, the student's submission is incorrect.
The alternative is to use either the GHC API (kinda hard), or play with Template Haskell (simpler, but still not that simple).
Yet another possibility is to load the student's code into GHCi and use the :browse command to dump out everything that's exported. You can then grep for the term you're interested in. That should be quite easy to automate.
There's a catch, however: foo :: x -> x and foo :: a -> a are the same type, even though textually they don't match at all. You might contemplate trying to normalise the variable names, but it's worse: foo :: Int -> Int and foo :: Num x => x -> x don't look remotely the same, yet one type is an instance of the other.
...which I guess means I'm saying that my answer is bad? :-(

Disable printing of IO results in GHCi?

When running IO actions in GHCi prompt it automatically runs the action and shows result, this is nice, but not for students trying to understand difference between IO and non-IO. Is there a way to change configuration of GHCi so that it runs the action, but shows something like <<IO Int action>> instead? Something more like result for ST actions (but action should be performed):
now it does:
> return 1 :: IO Int
1
> return 1 :: ST s Int
<<ST action>>
i would like:
> return 1 :: IO Int
<<IO Int action>>
> putStrLn "bla"
bla
<<IO () action>>
Edit:
I just found that IO is probably the only thing handled specially by GHCi, ST actually has instance for Show (ST s a) which returns "<<ST action>>". So maybe if I could disable this special treatment of IO it would be sufficient.
As for allowed code changes: manually changing evaluated expression is not an option. Change in libraries might be, but I would prefer not to do that (I considered creating wrapped IO type, but then interpreter will not run the action). If GHCi could automatically wrap IO actions somehow, that would be an option.
This is an interesting question. The only thing I can come up with is writing some kind of custom prelude module that exports a type called IO, but which isn't "the" I/O type that GHCi is special-casing.
Of course, this is no help at all unless the student remembers to import this rather than the real prelude. I suppose you could write that into the GHCi config file, but... well, it's certainly not perfect.
The only other way I can think of is to use the GHC-API to basically reimplement GHCi yourself. But that sounds like waaaay too much work...

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.

Which Monad do I need?

This is something of an extension to this question:
Dispatching to correct function with command line arguments in Haskell
So, as it turns out, I don't have a good solution yet for dispatching "commands" from the command line to other functions. So, I'd like to extend the approach in the question above. It seems cumbersome to have to manually add functions to the table and apply the appropriate transformation function to each function so that it takes a list of the correct size instead of its normal arguments. Instead, I'd like to build a table where I'll add functions and "tag" them with the number of arguments it needs to take from the command line. The "add" procedure, should then take care of composing with the correct "takesXarguments" procedure and adding it to the table.
I'd like to be able to install "packages" of functions into the table, which makes me think I need to be able to keep track of the state of the table, since it will change when packages get installed. Is the Reader Monad or the State Monad what I'm looking for?
No monad necessary. Your tagging idea is on the right track, but that information is encoded probably in a different way than you expected.
I would start with a definition of a command:
type Command = [String] -> IO ()
Then you can make "command maker" functions:
mkCommand1 :: (String -> IO ()) -> Command
mkCommand2 :: (String -> String -> IO ()) -> Command
...
Which serves as the tag. If you don't like the proliferation of functions, you can also make a "command lambda":
arg :: (String -> Command) -> Command
arg f (x:xs) = f x xs
arg f [] = fail "Wrong number of arguments"
So that you can write commands like:
printHelloName :: Command
printHelloName = arg $ \first -> arg $ \last -> do
putStrLn $ "Hello, Mr(s). " ++ last
putStrLn $ "May I call you " ++ first ++ "?"
Of course mkCommand1 etc. can be easily written in terms of arg, for the best of both worlds.
As for packages, Command sufficiently encapsulates choices between multiple subcommands, but they don't compose. One option here is to change Command to:
type Command = [String] -> Maybe (IO ())
Which allows you to compose multiple Commands into a single one by taking the first action that does not return Nothing. Now your packages are just values of type Command as well. (In general with Haskell we are very interested in these compositions -- rather than packages and lists, think about how you can take two of some object to make a composite object)
To save you from the desire you have surely built up: (1) there is no reasonable way to detect the number of arguments a function takes*, and (2) there is no way to make a type depend on a number, so you won't be able to create a mkCommand which takes as its first argument an Int for the number of arguments.
Hope this helped.
In this case, it turns out that there is, but I recommend against it and think it is a bad habit -- when things get more abstract the technique breaks down. But I'm something of a purist; the more duct-tapey Haskellers might disagree with me.

Resources