patternMinor
Print a sequence of n numbers
Viewed 0 times
numbersprintsequence
Problem
I have a simple function that takes an Integer n and return a string representing the array from 1..n.
The main function takes input n from the user and prints the nthLine out to screen:
Any tips on how this may be simplified/made better?
nthLine :: Integer -> String
nthLine n = intercalate " " $ map show [1..n]The main function takes input n from the user and prints the nthLine out to screen:
getInteger :: String -> Integer # This seems redundant
getInteger xs = (read xs)::Integer
nthLineStr :: String -> String # And so does this function
nthLineStr xs = nthLine (getInteger xs )
main = do line <- fmap nthLineStr getLine
putStrLn lineAny tips on how this may be simplified/made better?
Solution
You can use
Given the type signature of
This is now obviously a specialization of
You can perform eta-reduction again to write
Or you could use another
unwords in place of intercalate " ".Given the type signature of
getInteger :: String -> Integer the return type of read xs must be Integer in order for the type system to unify what you've written, making your type annotation on the function implementation there redundant. You can perform eta-reduction on getInteger then (that is, write it in pointfree style) and drop the xs for an implementation of—getInteger :: String -> Integer
getInteger = readThis is now obviously a specialization of
read, which isn't all that interesting. Look now to the implementation of nthLineStr where you can see that the result of getInteger xs is passed to nthLine. Because the type of nthLine is given as Integer -> String, the compiler can again determine that read must return an Integer if you change the definition of nthLineStr to—nthLineStr :: String -> String
nthLineStr xs = nthLine (read xs)You can perform eta-reduction again to write
nthLineStr as nthLineStr = nthLine . read. nthLineStr is a bit of a kludge though, in that it muddies the waters between your pure code and the outside world. Keep your (de-)serialization functions apart from the rest of your program, it shouldn't matter to the core logic of your application whether you were passed a String or a Text value or length encoded sequence of unit values ([()]).main :: IO ()
main = do n <- fmap read getLine
putStrLn $ nthLine nOr you could use another
Prelude function, interact :: (String -> String) -> IO () (a useful concept, but note this changes the semantics a bit).main :: IO ()
main = interact (nthLine . read)Code Snippets
getInteger :: String -> Integer
getInteger = readnthLineStr :: String -> String
nthLineStr xs = nthLine (read xs)main :: IO ()
main = do n <- fmap read getLine
putStrLn $ nthLine nmain :: IO ()
main = interact (nthLine . read)Context
StackExchange Code Review Q#85737, answer score: 4
Revisions (0)
No revisions yet.