Disable printing of IO results in GHCi? - haskell

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

Related

Haskell How to print info of some function in haskell like "ghci> :info func"

I'm new to haskell.
Sometimes I write some complicated functions that I'm not so sure about the types myself, so I don't define its type beforehand, compiling and running still work fine.
I want to know if I can print out the types of that function like in "ghci> :info someFunc" in the program, just to see how Haskell define its. Maybe something like this:
f x = 2*x
main :: IO()
main = do
print_info f
I know I can "ghci> :load program.hs" & then ":info f", but for me it is quite unconvenient & sometime working with ghci can be ugly.
Can't be done. You can sort of get close with Typeable, but polymorphism cannot be captured, even in principle.
Instead, I recommend that you set up the Haskell Language Server and connect your editor to it; most editors support at least the level of connection that lets you hover a term to see its type or add a type signature to a definition with a keybinding.

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? :-(

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.

Yesod's shakespearean templates (hamlet) and IO

In Hamlet, how does one uses the result of an IO operation inside #{...} ?
For instance :
someIO :: IO String
-----------------
$with stuff <- someIO
<p>#{stuff}
Fails with
No instance for (blaze-markup-0.6.0.0:Text.Blaze.ToMarkup
(IO String))
arising from a use of `toHtml'
I fear that I have not approached the problem from the right angle, could someone shed some light on this issue for me?
Thank you
Hamlet is just providing an alternate syntax for normal Haskell code, so like normal Haskell, you have to keep your impure actions separate. In other words, you need to run the IO action outside of the template.

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