How can I set OverloadedStrings in an ihaskell notebook? - haskell

I understand from the sample notebook that I should be able to enable and disable extensions as follows:
-- We can disable extensions.
:ext NoEmptyDataDecls
data Thing
<interactive>:1:1: error:
• ‘Thing’ has no constructors (EmptyDataDecls permits this)
• In the data declaration for ‘Thing’
-- And enable extensions.
:ext EmptyDataDecls
data Thing
However, when I try this with OverloadedStrings, I do not see any success. You can see from the below that T.lines is looking for String rather than Text. Why?
What am I misunderstanding or doing wrong?

Good news: the notebook above does have OverloadedStrings loaded correctly. The problem is you need to read the file with:
T.readFile
So
main :: IO ()
main = do
text <- T.readFile "./data.txt"
print $ T.lines text
This was confusing because the error highlighted T.lines rather than readFile. It turns out readFile does not produce a form of textual data that will automatically cast to the format required by T.lines (it produces String, not Text). You had to know that there is an entirely other function to call that does do that. The type system will not convert between these string-like formats for you. You must do this yourself by calling a file-reading function that explicitly returns a Text: here, T.readFile.

Related

haskell load data from 'script' file

I have been reading "learn you haskell for great good", and in this part:
"let’s put a string that represents a person in a script and then load that script in GHCi:
mysteryDude = "Person { firstName =\"Michael\"" ++
", lastName =\"Diamond\"" ++
", age = 43}"
We wrote our string across several lines like this for increased readability. If we want to read that string, we need to tell Haskell which type we expect in return:
ghci> read mysteryDude :: Person
But I don't know how to create the 'script', it's in mysteryDude.hs file, and then I need to load it with >:l mysteryDude.hs
Or what. But I tried it and I got this error:
*Main> read mysteryDude.hs :: Person
<interactive>:50:23: error:
Not in scope: type constructor or class ‘Person’
*Main> read mysterDude.hs :: Person
I see that in the web here, they change it, and don't do it in the same way, so, maybe it's an error.
But even if in this example is an error I would like to know how to write a 'script' and load data from it.
From comments I deduced the problem. :l in ghci forgets all previous :ls and all definitions that you made in REPL. You should either:
Make files import each other (avoiding import cycles). Filenames and module names must match.
import both files in ghci. Again, module names should match the names of files.
Make all your definitions in REPL's toplevel. You may use multiline snippets surrounding them by :{ :}. Not recommended tho

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.

Why type inference from pointfree source code dysfunctional? [duplicate]

This expression is incorrect.
f = show
However, in ghci this is legit
let f = show
Moreover, its type is changed to
() -> String
Is there any explanation of this phenomenon?
The ghci prompt behaves as if the ExtendedDefaultRules extension is enabled.
In particular this means that:
The unit type () is added to the start of the standard list of types
which are tried when doing type defaulting.
So to get the same behaviour from a source file, either compile with -XExtendedDefaultRules, or add {-# LANGUAGE ExtendedDefaultRules #-} to the top of the file.

When is the TemplateHaskell extension required in libraries providing TH deriving functions?

I was under the impression that using functions of type :: Name -> Q [Dec] had to be wrapped in a splice with the TemplateHaskell extension turned on, as e.g. documented in aeson:
$(deriveJSON defaultOptions ''(,,,))
But I just noticed the lens docs show using these TH functions without a splice (or TemplateHaskell), and I just tried it in a library I'm working on and it seems to work fine, even with something like this at the top level:
fmap concat $ forM [''X , ''Y , ''Z ] deriveFoo
Yet after making those modifications (removing from splice and removing pragma), I'm getting this error, unless I put a extensions: TemplateHaskell line in the test-suite block, which I don't really understand.
So is the splice thing a myth? And if so, then why do I need TemplateHaskell in an extensions list for the test-suite?

GHC: insert compilation date

I thought there would already be a question about this, but I can't find one.
I want my program to print out the date it was compiled on. What's the easiest way to set that up?
I can think of several possibilities, but none of them are what you'd call "easy". Ideally I'd like to be able to just do ghc --make Foo and have Foo print out the compilation date each time I run it.
Various non-easy possibilities that spring to mind:
Learn Template Haskell. Figure out how to use Data.Time to fetch today's date. Find a way how to transform that into a string. (Now my program requires TH in order to work. I also need to convince it to recompile that module every time, otherwise I get the compilation date for that module [which never changes] rather than the whole program.)
Write a shell script that generates a tiny Haskell module containing the system date. (Now I have to use that shell script rather than compile my program directly. Also, shell scripting on Windows leaves much to be desired!)
Sit down and write some Haskell code which generates a tiny Haskell module containing the date. (More portable than previous idea - but still requires extra build steps or the date printed will be incorrect.)
There might be some way to do this through Cabal - but do I really want to package up this little program just to get a date facility?
Does anybody have any simpler suggestions?
Using Template Haskell for this is relatively simple.
You just need to:
Run IO action within Template Haskell monad:
runIO :: IO a -> Exp a
Then create a string literal with:
stringE :: String -> ExpQ
Put a whole expression within a quasiquote.
$( ... )
This program will print time of its compilation:
{-# LANGUAGE TemplateHaskell #-}
import Language.Haskell.TH
import Data.Time
main = print $(stringE =<< runIO (show `fmap` Data.Time.getCurrentTime))
You may put the relevant fragment into a module that imports all other modules to make sure it is recompiled.
Or take current revision information from your versioning system. See: TemplateHaskell and IO
The preprocessor helpfully defines __DATE__ and __TIME__ macros (just like in C), so this works:
{-# LANGUAGE CPP #-}
main = putStrLn (__DATE__ ++ " " ++ __TIME__)
This is probably simpler than Michal's suggestion of Template Haskell, but doesn't let you choose the format of the date.

Resources