I'm currently in the process of solving euler problems to improve in Haskell. Though, my attempt at solving problem n° 43 produces no output.
Just to be clear, I'm not asking for help on the "problem algorithmic" part, even if I'm wrong. I'm specifically asking for help on the Haskell part.
So, I divided my attempt into simple functions. First I build a list holding all 0-9pandigital numbers, then I define functions to cut those numbers into the interesting part and finally I filter only the correct ones:
import Data.List
main = print $ foldl1 (+) goodOnes
pands = [read x :: Integer | x <- permutations "0123456789", head x /= '0']
cut3from :: Integer -> Integer -> Integer
cut3from x n = mod (div x nd) 1000
where
l = fromIntegral $ length $ show x :: Integer
nd = 10 ^ (l - 3 - n)
cut :: Integer -> [Integer]
cut x = map (cut3from x) [1..7]
testDiv :: Integral a => [a] -> Bool
testDiv l = and zipped
where
zipped = zipWith mult l [2, 3, 5, 7, 11, 13, 17]
mult :: Integral a => a -> a -> Bool
mult a b = mod a b == 0
goodOnes = filter (testDiv.cut) pands
Though, when compiling it (with -O2) and executing it, it outputs nothing. Even with +RTS -s.
I'd like advice on two points mainly:
why is this code wrong, how to improve it
how could I have debugged it myself
as a side point, if you have advice on how to handle Integer and Ints easily, please post them. I find it troublesome to use both together.
But any other remark is welcome!
EDIT: it seems that GHCi slowly builds the result list goodOnes and is able to answer after a long time (only in GHCi, when compiled it's still as reported). That's certainly not a behaviour I can wish to observ in my programs. How could I fix that ?
EDIT2: it now works when compiled too (code unchanged). I'm puzzled about all those inconsistencies and would welcome any explanation!
EDIT3: semihappy ending: after a reboot, all went back to normal ~~
To answer "how could I have debugged it myself":
Check out ghci.
prompt$ ghci
GHCi, version 6.12.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.
Loading package ffi-1.0 ... linking ... done.
Prelude>
It's an interactive interpreter that allows you to:
load files and play with the contents
Prelude> :load myfile.hs
[1 of 1] Compiling Main ( myfile.hs, interpreted )
Ok, modules loaded: Main.
*Main> xyz "abc"
*Main> 3
type in definitions and use them
*Main> let f x = x + 3
evaluate expressions and see the results
*Main> f 14
17
inspect types and kinds
*Main> :t f
f :: (Num a) => a -> a
*Main> :k Maybe
Maybe :: * -> *
Make sure you test each of the little pieces before you test the whole shebang -- it's easier to find problems in small things than in big ones. Check out QuickCheck if you're into unit tests.
For the Ints vs. Integers issue, you could sidestep the issue by only using Integers (of course, they may be less efficient: YMMV). Data.List has functions prefixed with generic, i.e. genericLength which are quite useful.
Here's how I compiled and ran it:
prompt$ ghc euler43.hs
prompt$ ./a.out
<some number is printed out>
Related
My goal is to get a list of N random items taken from an input list and see the result in GHCI. I decided to shuffle the input list, then take the first N elements from it (i.e. slice first elements). I am using shuffle function from random-fu module Data.Random.List.
Here's the code I currently have and at least it can be compiled
import Data.Random
import Data.Random.List
rndSelect :: [a] -> Int -> RVar [a]
rndSelect l n
= do
l' <- shuffle l;
return $ take n l'
But when I run rndSelect "abcdefg" 3 in GHCI prompt, I get the following error:
<interactive>:1:1: error:
• No instance for (Show (RVar [Char]))
arising from a use of ‘print’
• In a stmt of an interactive GHCi command: print it
I think I know what it means. RVar doesn't derive Show. I guess I should modify my function so that it gets shuffled RVar[a] and then somehow take a list of the first N elements and convert it to IO action.
Here's one of my failed attempts:
rndSelect :: [a] -> Int -> IO ()
rndSelect l n
= do
l' <- shuffle l;
l'' <- take n l'
s <- runRVar l'' StdRandom
putStrLn s
I know, that it is messed up and raises errors on top of errors. I am beginner in Monads, "do" blocks and things like that in Haskell
I would be glad if someone help me to fix my approach, but if you know alternative way to achieve my goal, I will be happy to see it as well. Thank you very much!
Your rndSelect :: [a] -> Int -> RVar [a] is perfectly fine, but it should be obvious that the resulting RVar [a] can't really be shown. After all, this is a probability distribution. Such distributions “contain” in general infinitely many possible outcomes. All you can hope to do is to show samples from the distribution. Since GHCi allows you to do IO, it's easy to obtain samples right there:
*Main> sample $ rndSelect "abcdefg" 3
"def"
*Main> sample $ rndSelect "abcdefg" 3
"ecb"
*Main> sample $ rndSelect "abcdefg" 3
"fbc"
*Main> :m +Control.Monad
*Main Control.Monad> sample . replicateM 20 $ rndSelect "abcdefg" 3
["gef","adf","cga","bfd","eab","bgd","gdf","abg","egc","bda","ceb","fbd","agb","egc","acb","bga","gbd","edb","egb","egd"]
I've made a calculator in haskell which I run from within GHCi. However since the final number can be an integer or double I've made the type declaration
calc :: String -> Either Integer Double
However the output of the function always has either left or right in front of it for example
Left 7
Right 8.4
Is there a way I can stop the left and right being printed?
When you evaluate this function, GHCi automatically calls putStrLn . show on the result. It is the show function for Either Integer Double which is adding the Left and Right strings.
To avoid this, you can use either show show instead, which will apply the show function only to the numbers stored inside the Either, so
> putStrLn . either show show $ calc ...
should give you what you want.
The fancy way
(Probably, the other, less fancy solution below is better for you)
If you're only concerned about ghci, there's now (GHC>=7.6) the possibility to use a custom print function. You'd just specify, say,
type CalcResult = Either Integer Double
calcPrint :: CalcResult -> IO()
calcPrint (Left intg) = print intg
calcPrint (Right floatng) = print floatng
and then load ghci by
$ ghci YourModule.hs -interactive-print=YourModule.calcPrint SpecPrinter
This way, it's going to be a bit annoying: calcPrint can only use CalcResult, so you wouldn't be able to display anything else. To get around this, you can use a type class,
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE OverlappingInstances #-}
data CalcResult -- We must prevent the 'Show' instance of 'Either' from
= IntegerResult Integer -- getting in our way. (This type is better anyway,
| FloatingResult Double -- you might want to add more types (e.g. 'Complex')
-- later, which is no good with 'Either'.)
class CalcShow c where
calcShow :: c -> String
instance (Show c) => CalcShow c where
calcShow = show
instance CalcShow CalcResult where
calcShow (IntegerResult intg) = show intg
calcShow (FloatingResult floatng) = show floatng
calcPrint :: CalcShow c => c -> IO()
calcPrint = putStrLn . calcShow
This way you will be able to display calculation results the way you'd like, as well as anything in the old Show class:
$ ghci-7.6 GHCI_Customprint.hs -interactive-print=GHCI_Customprint.calcPrint
GHCi, version 7.6.2: 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 1] Compiling GHCI_Customprint ( GHCI_Customprint.hs, interpreted )
Ok, modules loaded: GHCI_Customprint.
*GHCI_Customprint> "blubb"
"blubb"
*GHCI_Customprint> [1..5]
[1,2,3,4,5]
*GHCI_Customprint> IntegerResult 39
39
*GHCI_Customprint> FloatingResult $ -236.24983e+89
-2.3624983e91
The other solution
As I said, you should be using a custom data type as your result, not Either. Why, if you have such a type you might as well give it a Show instance that does what you want:
instance Show CalcResult where
show (IntegerResult intg) = show intg
show (FloatingResult floatng) = show floatng
For your purposes, this will probably be just fine, you can use it in ghci without any extra tweaks and it does what you want. Only, there's a kind of law that a Show instance should produce valid Haskell code. But that's actually ok, because you can make 3 or 27.8 valid "constructors" for CalcResult!
instance Num CalcResult where
fromInteger = IntegerResult
IntegerResult a + IntegerResult b = IntegerResult $ a+b
...
instance Floating CalcResult where
fromRational = FloatingResult . fromRational
...
I am fresh in haskell, and I defined a func in Haskell :
febs :: (Integral a)=> a -> a
febs n
| n<=0 =0
| n==1 =1
| n==2 =1
| otherwise =febs(n-1)+febs(n-2)
but, it runs so slow, and when I do "febs 30", it will take about 10s,
and I do the same func in C++, it runs very fast.
int febs(int n)
{
if(n == 1 || n ==2)
{
return 1;
}
return febs(n-1)+febs(n-2);
}
Is there any way to promote my haskell func speed?
This is an odd comparison, for the following reasons:
You don't say whether you're compiling the Haskell code, or with what options. If you're just running it in ghci, then of course it will be slow - you're comparing interpreted code with compiled code.
Your Haskell code is polymorphic whereas your C++ code is monomorphic (that is, you've used a type class Integral a => a -> a instead of the concrete type Int -> Int). Your Haskell code is therefore more general than your C++ code, because it can handle arbitrarily large integers instead of being restricted to the range of an Int. It's possible that the compiler will optimize this away, but I'm not certain.
If I put the following code in a file fib.hs
fibs :: Int -> Int
fibs n = if n < 3 then 1 else fibs (n-1) + fibs (n-2)
main = print (fibs 30)
and compile it with ghc -O2 fib.hs then it runs fast enough that it appears instantaneous to me. You should try that, and see how it compares with the C++ code.
Try compiling with optimization. With GHC 7.4.1 with -O2, your program runs quite quickly:
$ time ./test
832040
real 0m0.057s
user 0m0.056s
sys 0m0.000s
This is with main = print (febs 30).
Regarding the polymorphism considerations in Chris Taylor's answer, here's febs 40 with OP's polymorphic Fibonacci function:
$ time ./test
102334155
real 0m5.670s
user 0m5.652s
sys 0m0.004s
And here is a non-polymorphic one, i.e. with OP's signature replaced with Int -> Int:
$ time ./test
102334155
real 0m0.820s
user 0m0.816s
sys 0m0.000s
Per Tikhon Jelvis' comment, it'd be interesting to see if the speedup is due to replacing Integer with Int, or due to getting rid of polymorphism. Here's the same program again, except with febs moved to a new file per Daniel Fischer's comment, and with with febs :: Integer -> Integer:
$ time ./test
102334155
real 0m5.648s
user 0m5.624s
sys 0m0.008s
Again, with febs in a different file, and with the same polymorphic signature as originally:
$ time ./test
102334155
real 0m16.610s
user 0m16.469s
sys 0m0.104s
You could also write the function like this:
fibs = 0:1:zipWith (+) fibs (tail fibs)
It is very fast, even for big 'n' executes immediately:
Prelude> take 1000 fibs
Simple question. Is it possible to check the type of a variable that is only alive within a function?
For example:
main = do
x <- something
How can I check the type of x?
I can't do :type x in ghci because x is not global.
Another way (quite similar to RobAgar's and hacky as well) is to explicitly specify some wrong type for the local variable in question, e.g.:
main = do
x <- getArgs
x :: () -- let's cast it to unit! ;)
print $ head x
Then ghci will give us an error:
Couldn't match expected type `()' with actual type `[String]'
which shows that the actual type of "x" is [String].
There is a hacky way:
main = do
x <- something
foo x
where foo is any old function which doesn't take an argument of the type you think x might be. You'll get a nice error from GHC which includes the type expected by foo and the type actually passed in.
You can use the GHCi Debugger:
> ghci a.hs
GHCi, version 7.0.4: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
[1 of 1] Compiling Main ( a.hs, interpreted )
Ok, modules loaded: Main.
*Main> :break 4
Breakpoint 0 activated at a.hs:4:8-14
*Main> :main
Stopped at a.hs:4:8-14
_result :: IO String = _
[a.hs:4:8-14] *Main> :list
3 main = do
4 x <- getLine
^^^^^^^
5 return x
[a.hs:4:8-14] *Main> :step
asd
Stopped at a.hs:5:3-10
_result :: IO String = _
x :: String = _
[a.hs:5:3-10] *Main> :t x
x :: String
There is no easy way to do this. If your something function is in the global scope, you can check the type of that function. If it really is in your main function, its type is going to be IO SomeType, where SomeType is probably what you're looking for.
Another option is Scion which is basically an external wrapper over the GHC api which acts as a server providing IDE-like capabilities for editors like Emacs and Vim.
In the readme, it mentions the "experimental" command C-c C-t which shows the type of the identifier at point, including local identifiers. However, this will only work if your file type-checks.
This lets you find out the type of a local declaration without compiling your file or loading into GHCi, which means it won't disrupt your flow of thought as much.
This is sort of the obvious non-answer. Given a local binding of the form
x <- something
In order to know the type of x, you merely need to know the type of something. Given something has the type m a (for some Monad m), x must therefore have the type a.
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.