Haskell: Building a range of numbers from command line arguments
I’m working through some of the SICP problems in Haskell and for problem 1.22 you need to write a function which will indicate the first 3 prime numbers above a starting value.
It is also suggested to only consider odd numbers so to find the prime numbers above 1000 the function call would look like this:
> searchForPrimes [1001,1003..] [1009,1013,1019]
I wanted to be able to feed in the range of numbers from the command line so that I’d be able to call the function with different values and see how long it took to work it out.
I initially tried passing the above array to the program as a command line argument wrapped in a string and then parse it using read which works if you provide a complete array:
> read "[1,2]" :: [Int] [1,2]
But not so well for ranges:
> read "[1,2..]" :: [Int] *** Exception: Prelude.read: no parse
Instead I thought I could just provide the first two values for the proposed range and then work from there.
To help me do this I came across the enumFromThen function which has the following signature:
> :t enumFromThen enumFromThen :: Enum a => a -> a -> [a]
From the Haskell source this function seems to call the literal range syntax which I mentioned above:
enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..]
I was actually expecting there to be a literal range syntax definition which made a call to the various enumFrom… methods since the literal syntax seems more like syntactic sugar on top of the function call approach but apparently not!
I use it like this:
main = do args <- getArgs let (first:second:_) = map read args in putStrLn $ show $ searchForPrimes (enumFromThen first second)
Which I suppose could just as easily be written like this:
main = do args <- getArgs let (first:second:_) = map read args in putStrLn $ show $ searchForPrimes ([first, second..])
And I’ve gone full circle!