Why can't I run main interactively? - haskell

The program (Main.hs, found on SO) looks like this
import Control.Monad.Random
main :: IO ()
main = do
gen <- getStdGen
let values = evalRand diceSums gen
print . take 10 $ values
-- Generate sums from rolling two dice
diceSums :: RandomGen g => Rand g [Int]
diceSums = do
xs <- dieRolls
ys <- dieRolls
return $ zipWith (+) xs ys
-- Single die roll function.
dieRolls :: RandomGen g => Rand g [Int]
dieRolls = getRandomRs (1, 6)
I then run
stack ghci
Prelude> :l Main.hs
[1 of 1] Compiling Main ( Main.hs, interpreted )
Ok, one module loaded.
*Main> main
<interactive>:2:1: error:
* Variable not in scope: main
* Perhaps you meant `min' (imported from Prelude)
*Main> :t dieRolls
<interactive>:1:1: error: Variable not in scope: dieRolls
If I try and compile I get
ghc Main.hs
[1 of 1] Compiling Main ( Main.hs, Main.o )
Main.hs:1:1: error:
The IO action `main' is not defined in module `Main'
What am I doing wrong?

Might it be that stack is insisting on you adding the module declaration at the top of the module,
module Main where
(this seems related, though according to it, without the declaration, main should still be available -- though dieRolls indeed shouldn't.)

Not sure why main doesn't work, but the correct way to run main function from GHCi is :main. This way you can pass arguments to your program.

Related

Using RandomGen in newsynth

I'm new to Haskell and am trying to get some code up and running on a bit of a tight schedule, which is why I'm doing something more complicated than the absolute basics. I'm using the package newsynth and would like to use the function root_of_negative_one (documentation, source). In GHCi, I run the following commands:
Prelude> import Quantum.Synthesis.Diophantine
Prelude Quantum.Synthesis.Diophantine> :set -package random
Prelude Quantum.Synthesis.Diophantine> import System.Random
Prelude Quantum.Synthesis.Diophantine System.Random> let g = getStdGen
Prelude Quantum.Synthesis.Diophantine System.Random> let x = root_of_negative_one g 5
to try to get a square root of -1 mod 5. GHCi returns:
<interactive>:7:9: error:
• No instance for (RandomGen (IO StdGen))
arising from a use of ‘root_of_negative_one’
• In the expression: root_of_negative_one g 5
In an equation for ‘x’: x = root_of_negative_one g 5
I know that root_of_negative_one needs an input of type RandomGen but I seem to have not understood the RandomGen documentation well enough to execute this. Any help is appreciated. Thanks!
root_of_negative_one needs a StdGen, but getStdGen is an IO StdGen. You need to do g <- getStdGen instead of let g = getStdGen.

Haskell - Not in scope: class Gen

In the main module we have:
import System.Environment
import System.Random
main = do
args <- getArgs
random <- choose (0,100000) :: Gen Int
newCards = baralhar (mkStdGen random) baralho40
putStrLn $ "-----The End -----"
and we get this error when we compile:
Bisca.hs:13:36: error:
Not in scope: type constructor or class ‘Gen’
|
13 | random <- choose (0,100000) :: Gen Int
| ^^^
I don´t understand what the Gen means and what the solution could be
Hoogle reports that choose is a function from QuickCheck (see here). Gen is a type from Test.QuickCheck.Gen.
You just need to add an import statement for the QuickCheck library (Test.QuickCheck and Test.QuickCheck.Gen) and make sure your build system is aware of the library.

IO/Monadic assign operator causing ghci to explode for infinite list

Consider the following program. It runs forever and does nothing useful, but the memory consumption in ghci is constant :
--NoExplode.hs
module Main (main) where
test :: [Int] -> IO()
test lst = do
print "test"
rList lst
rList :: [Int] -> IO ()
rList [] = return ()
rList (x:xs) = do
rList xs
main = do
test [1..]
Now consider the following trivially modified version of the above. When this program is run in ghci the memory explodes. The only difference is that print "test" is now assigned to x in the do block of test.
--Explode.hs
module Main (main) where
test :: [Int] -> IO()
test lst = do
x <- print "test"
rList lst
rList :: [Int] -> IO ()
rList [] = return ()
rList (x:xs) = do
rList xs
main = do
test [1..]
Why does changing print "test" to x <- print "test" cause ghci to blow up?
p.s. I came across this when trying to understand Memory exploding upon writing a lazy bytestring to file in ghci, and the problem there (I think) essentially distils to the above. Thanks
Disclaimer: I'm not a GHCi expert, and also not that good with GHC core. Now that I've lost my credibility, lets try to understand what happens:
GHCi and CAFs
GHCi retains all evaluated CAFs:
Normally, any evaluation of top-level expressions (otherwise known as CAFs or Constant Applicative Forms) in loaded modules is retained between evaluations.
Now you might wonder why there's such a big difference between both versions. Lets have a look at the core with -ddump-simpl. Note that you might want to drop -dsuppress-all when you dump the programs yourself.
Dumps of your programs
Non-exploding version:
❯ ghc SO.hs -ddump-simpl -fforce-recomp -O0 -dsuppress-all
[1 of 1] Compiling Main ( SO.hs, SO.o )
==================== Tidy Core ====================
Result size of Tidy Core = {terms: 29, types: 28, coercions: 0}
$dShow_rq2
$dShow_rq2 = $fShow[] $fShowChar
Rec {
rList_reI
rList_reI =
\ ds_dpU ->
case ds_dpU of _ {
[] -> return $fMonadIO ();
: x_aho xs_ahp -> rList_reI xs_ahp
}
end Rec }
main
main =
>>
$fMonadIO
(print $dShow_rq2 (unpackCString# "test"))
(rList_reI (enumFrom $fEnumInt (I# 1)))
main
main = runMainIO main
The important part is the location of [1..], almost at the end:
enumFrom $fEnumInt (I# 1))
As you can see, the list isn't a CAF. But what happens if we instead use the exploding version?
Exploding version
❯ ghc SO.hs -ddump-simpl -fforce-recomp -O0 -dsuppress-all
[1 of 1] Compiling Main ( SO.hs, SO.o )
==================== Tidy Core ====================
Result size of Tidy Core = {terms: 32, types: 31, coercions: 0}
$dShow_rq3
$dShow_rq3 = $fShow[] $fShowChar
Rec {
rList_reI
rList_reI =
\ ds_dpV ->
case ds_dpV of _ {
[] -> return $fMonadIO ();
: x_ahp xs_ahq -> rList_reI xs_ahq
}
end Rec }
lst_rq4
lst_rq4 = enumFrom $fEnumInt (I# 1)
main
main =
>>=
$fMonadIO
(print $dShow_rq3 (unpackCString# "test"))
(\ _ -> rList_reI lst_rq4)
main
main = runMainIO main
There's suddenly a new top-level expression, namely lst_rq4, which generates the list. And as seen before, GHCi retains the evaluations of top-level expressions, so lst_rq4 will also be retained.
Now there is an option to discard the evaluations:
Turning on +r causes all evaluation of top-level expressions to be discarded after each evaluation (they are still retained during a single evaluation).
But since "they are still retained during a single evaluation" even :set +r won't help you in this case. Unfortunately I cannot answer why GHC introduces a new top-level expression.
Why does this even happen in optimized code?
The list is still a top-level expression:
main2
main2 = eftInt 1 2147483647
Funny enough, GHC actually doesn't create an infinite list, since Int is bounded.
How can one get rid of the leak?
In this case you can get rid of it if you place the list in test:
test = do
x <- print "test"
rList [1..]
This will prevent GHC from creating a top-level expression.
However, I can't really give a general advise on this. Unfortunately, my Haskell-fu isn't yet good enough.

Proper way to import things already defined in the Prelude in Haskell

I'm trying to define a Foldable instance in Haskell and I have some problem with import.
So first try :
module MyList
where
import Data.Foldable
data MyList a = MyList [a]
instance Foldable (MyList) where
foldr f b (MyList as) = foldr f b as
Result (normal but annoying)
Ambiguous occurrence `foldr'
So, I guess I have to hide it from the Prelude :
module MyList
where
import Prelude hiding (foldr)
import Data.Foldable
data MyList a = MyList [a]
instance Foldable (MyList) where
foldr f b (MyList as) = foldr f b as
This compile, I load into ghci and try some basic stuff :
*MyList> foldr (:) "" (MyList "hello")
"hello"
*MyList> foldl (flip (:)) "" (MyList "hello")
<interactive>:1:0:
Ambiguous occurrence `foldl'
It could refer to either `Prelude.foldl', imported from Prelude at MyList.hs:4:0-28
or `Data.Foldable.foldl', imported from Data.Foldable at MyList.hs:5:0-19
*MyList>
So foldr works, but foldl doesn't. My first question is
Do I have to hide manually every single method defined in Data.Foldable from the Prelude is their a nice way to do it ?.
To avoid this problem , I tried to do an qualified import :
module MyList
where
import qualified Data.Foldable as F
data MyList a = MyList [a]
instance F.Foldable (MyList) where
foldr f b (MyList as) = foldr f b as
Seems to compile in ghc but
*MyList> foldr (:) "" (MyList "hello")
<interactive>:1:14:
Couldn't match expected type `[Char]'
against inferred type `MyList Char'
In the third argument of `foldr', namely `(MyList "hello")'
In the expression: foldr (:) "" (MyList "hello")
In the definition of `it': it = foldr (:) "" (MyList "hello")
foldr is not found but suprisingly F.foldr works in ghci.
*MyList> F.foldr (:) "" (MyList "hello")
"hello"
But in ghci only, if I'm trying to import MyList in file, foldr, F.foldr, MyList.F.foldr and MyList.foldr doesn't work.
Why does it work in ghci but not in real ?
I guess I have to import Data.Foldable again (and again in every files using MyList)
Is there a better way to do it (like exporting Data.Foldable in MyList) ?
(I'm a newbie in Haskell and especially with modules)
After having a couple of responses, it seems there is no clean solution to this problem. However, I'm pretty sure I'm not the first doing that, so
What is the common practice to deal with that kind of problem?
Thanks for you help.
Why does it work in ghci but not in real?
Because in your GHCi session you were typing expressions in the context of the MyList module, so F.foldr was in scope, but if you import MyList into another module then only the names exported by MyList, and the other modules you imported, are in scope.
Your guess is correct - in every module using Data.Foldable.foldr, you have to
import qualified Data.Foldable as F
The names exported by a module are unqualified; the qualification or not of those names is decided when the module is imported.
There have been proposals over the years to allow exporting qualified names, but to date nothing has been implemented.
Regarding the implicit Prelude import, you could add the following language pragma, and then explicitly import things from Prelude, but it might get uglier than simply hiding things from the Prelude or using an qualified import of Data.Foldable.
{-# LANGUAGE NoImplicitPrelude #-}
import Prelude (someFunction)
Why it might get uglier? Because you might have to import data types and functions that are taken for granted, or even functions that aren't explicitly used in the code:
{-# LANGUAGE NoImplicitPrelude #-}
module Main (main) where
-- we import fromInteger although it's not explicitly used
import Prelude (Int, foldl, fromInteger, (+), putStrLn, (.), ($), IO, show)
sum :: [Int] -> Int
sum = foldl (+) 0
main :: IO ()
main = putStrLn . show $ sum [1,2,3]
I told you about this not because it's a good solution, but just to know that there's such a thing.
Here's a variant of Thomas Eding solution, with less typing. Basically, you can import (in Prelude') Prelude hiding some functions, and then reexport Prelude; this will export Prelude minus those functions. This technique is generally useful to write a frontend module re-exporting only some functions in a library.
You can then reexport also Data.Foldable.
Where I replaced some Prelude functions with equivalents (examples for Foldable and Category).
module Prelude2 (module Prelude, module Data.Foldable, module Control.Category) where
import Prelude hiding (id, (.), foldr)
import Data.Foldable (Foldable, foldr) -- You might want to import everything.
import Control.Category (Category((.), id))
-- Try out replacing with:
-- import Control.Category ()
-- to see that no (.) is available.
Usage:
module Foo where
import Prelude()
import Prelude2
To wit, notice the types of foldr and (.) in Foo, as shown by GHCi:
$ ghci Foo.hs
GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[1 of 2] Compiling Prelude2 ( src-lib/Prelude2.hs, interpreted )
[2 of 2] Compiling Foo ( /Users/pgiarrusso/AeroFS/Repos/pts-bluevelvet/src-lib/Foo.hs, interpreted )
Ok, modules loaded: Foo, Prelude2.
*Foo> :t foldr
foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
*Foo> :t (.)
(.) :: Category cat => cat b c -> cat a b -> cat a c
*Foo>
If you try the suggestion of replacing
import Control.Category ()
GHCi will show you that (.) is not defined at all in Foo:
*Foo> :r
[1 of 2] Compiling Prelude2 ( src-lib/Prelude2.hs, interpreted )
[2 of 2] Compiling Foo ( /Users/pgiarrusso/AeroFS/Repos/pts-bluevelvet/src-lib/Foo.hs, interpreted ) [Prelude2 changed]
Ok, modules loaded: Foo, Prelude2.
*Foo> :t (.)
<interactive>:1:1: Not in scope: `.'
You could make a Prelude' module that exports only the stuff you want. Then you could begin your actual module as follows:
import Prelude ()
import Prelude'
import Data.Foldable
Granted you have to do the grunt work in Prelude', but at least it is reusable.
Clarification:
Prelude'.hs:
module Prelude' (
id
, Num (..)
, everthing you want exported for your 'customized' prelude module goes in this list
) where
I've re-read your question and some of your comments and I guess the closest you can get to what you want is something like this:
module MyList
(
module Data.Foldable,
MyList(..)
)
where
import Data.Foldable
import Prelude (($))
data MyList a = MyList [a]
instance Foldable (MyList) where
foldr f b (MyList as) = foldr f b as
Basically, MyList re-exports the Data.Foldable module, so that someone using your module won't have to import Data.Foldable again, but... she will have to hide some functions from the Prelude.
module Main (main) where
import Prelude hiding (foldr)
import MyList
mySum :: MyList Int -> Int
mySum = foldr (+) 0
main :: IO ()
main = putStrLn . show . mySum $ MyList [1,2,3]
IMHO, this is a good thing. You should not decide how and what someone imports in his own modules.

Having trouble using the BinaryDerive.hs Script, for generating Binary instances

I'm trying to run the BinaryDerive.hs script as per the instructions in the Data.Binary doc, which states:
To derive the instance for a type,
load this script into GHCi, and bring
your type into scope. Your type can
then have its Binary instances derived
as follows:
$ ghci -fglasgow-exts BinaryDerive.hs
*BinaryDerive> :l Example.hs
*Main> deriveM (undefined :: Drinks)
However when I try to follow those instructions I get:
c:\Scripts\Haskell>$ ghci -fglasgow-exts BinaryDerive.hs
*BinaryDerive> :l TemperatureRecord.hs
[1 of 1] Compiling TemperatureRecord (TemperatureRecord.hs, interpreted )
Ok, modules loaded:TemperatureRecord.
*TemperatureRecord> deriveM (undefined :: TemperatureRecord)
(interactive):1:0: Not in scope: 'deriveM'
I am assuming that there is an additional step that was not specified that a beginner, like myself would not be aware of. It seems the root of the problem is that loading the TemperatureRecord takes BinaryDerive out of scope. Anyone have any ideas?
My understanding of ghci's loading/namespacing mechanisms is full of holes, but since nobody else has answered, here are some guessses:
Try :m + BinaryDerive after :l Example.hs
Add import BinaryDerive at the top of Example.hs
Don't add module TemperatureRecord where at the top of Example.hs
try
$ ghci -fglasgow-exts
Prelude> :l BinaryDerive TemperatureRecord
the .hs's are not necessary
Then you can access TemperatureRecord in a similar manner to this example (JSON Doc type taken from Real World Haskell, with some added Data and Typeable derives)
$ ghci -fglasgow-exts -XDeriveDataTypeable
Prelude> :l Binaryderive JSON
[1 of 2] Compiling JSON ( JSON.hs, interpreted )
[2 of 2] Compiling BinaryDerive ( Binaryderive.hs, interpreted )
Ok, modules loaded: BinaryDerive, JSON.
*BinaryDerive> deriveM (undefined::JSON.Doc)
instance Binary JSON.Doc where
put Empty = putWord8 0
put (Char a) = putWord8 1 >> put a
put (Text a) = putWord8 2 >> put a
put Line = putWord8 3
put (Concat a b) = putWord8 4 >> put a >> put b
put (Union a b) = putWord8 5 >> put a >> put b
get = do
tag_ <- getWord8
case tag_ of
0 -> return Empty
1 -> get >>= \a -> return (Char a)
2 -> get >>= \a -> return (Text a)
3 -> return Line
4 -> get >>= \a -> get >>= \b -> return (Concat a b)
5 -> get >>= \a -> get >>= \b -> return (Union a b)
_ -> fail "no parse"
Thanks everyone for the answers. I tried both of them and neither worked, however, the answers I saw did lead me too a solution.
$ ghci -fglasgow-exts -XDeriveDataTypeable
Prelude> :l Binaryderive TemperatureRecord
Prelude> :m Binaryderive TemperatureRecord
Prelude BinaryDerive TemperatureRecord>deriveM (undefined :: TemperatureRecord)
The above worked for me. However, I am not using that solution in practice. I am working on getting a more automatic solution to work. Anyway thanks for helping me get something that works.

Resources