HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

"Hell Difficulty" Haskell Fast & Hard

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
fasthardhellhaskelldifficulty

Problem

I'm a complete neophyte to Haskell with only a smidge of FP experience – I did some Racket programming academically and have written some semi-FP JavaScript professionally, but now I'm trying to learn Haskell (and FP better). So I read Haskell Fast & Hard with no problems up until the last chapter.

Monads.


Make a program that sums all of its arguments. Hint: use the function getArgs.

I eventually wrote a program that nominally achieves this requirement, but it felt very hacky. For reference, here is a "correct" program by the author that I think I was supposed to model after. It sums the numbers in a comma-delimited string.

import Data.Maybe

maybeRead :: Read a => String -> Maybe a
maybeRead s = case reads s of
                  [(x,"")]    -> Just x
                  _           -> Nothing
getListFromString :: String -> Maybe [Integer]
getListFromString str = maybeRead $ "[" ++ str ++ "]"
askUser :: IO [Integer]
askUser = do
  putStrLn "Enter a list of numbers (separated by comma):"
  input  return l
          Nothing -> askUser
-- show
main :: IO ()
main = do
  list <- askUser
  print $ sum list


Based on the above approach, I wrote a function to convert the list of argument-strings back into a comma-delimited string so that most of the other functions could work unchanged.

import Data.Maybe
import System.Environment (getArgs)

maybeRead :: Read a => String -> Maybe a
maybeRead s = case reads s of
                  [(x,"")]    -> Just x
                  _           -> Nothing
getListFromString :: String -> Maybe [Integer]
getListFromString str = maybeRead $ "[" ++ str ++ "]"
getArgsAsString :: [String] -> String
getArgsAsString [] = "0"
getArgsAsString (x:xs) = x ++ "," ++ getArgsAsString xs
askUser :: [String] -> [Integer]
askUser input = case (getListFromString (getArgsAsString input)) of
            Just l  -> l
            Nothing -> error "failsauce"
main :: IO ()
main = do
  input <- getArgs
  print $ sum (askUser input)


I am try

Solution

There's very little I would salvage from the model code.

  • Converting the arguments list into comma-separated string is a little hackish and not very efficient (nevertheless it works, and I'd be totally OK with it for a quick throw away script). Therefore I would not use getListFromString.



  • askUser is not needed since we're not interacting with the user.



  • There's already an alternative to maybeRead, in Text.Read called readMaybe.



This is how I would implement it:

`import System.Environment (getArgs)
import Text.Read (readMaybe)

main :: IO ()
main = do
values

Context

StackExchange Code Review Q#38394, answer score: 7

Revisions (0)

No revisions yet.