title: I am stuck on haskell input
body: <p>I'm new to haskell and I have an assignment that involves parsing a string into a tree and doing some junk with it.
  I've just about finished (everything is functionally fine right now) but as I've gone through the development, I've been using a static string definition as opposed to entering the input each time.</p>
  
  <p>Here is an example input.
  ex1 = "C1,8R1+4;R3-4C2C7+4;R5R2-3C1-6+3;R2-3C6+2;"</p>
  
  <p>The last thing I need to do is handle user input (the input should come from standard in, not some definition).
  Not only do I not know how to get input for sure, but I'm beginning to think I'm royally screwed because of the nature of haskell. I mean, it seems like the entire language is just nested statements within nested statements with recursive nested statements and so on and so forth. It's a confusing mess to me. I'm not even sure what to ask... so far my attempts at getting user input have meant that I need to start throwing around the input as a parameter to every single function in the entire program just to get it to compile.
  Is there any way I can turn user input into a definition like the above? Or perhaps even just cheat with a global string variable? I'm desperate :( Thanks.</p>
  
  <p>I know it's probably bad to be posting my entire program but I feel like I need to so I can show how intertwined it all is, making it difficult to figure out how to proceed.</p>
  
  <p>It is the function createNodeContentList (near the bottom) that actually uses the definition of ex1.</p>
  
  <pre><code>import Text.Regex.Posix
  import Data.List.Split
  
  ex1 = "C1,8R1+4;R3-4C2C7+4;R5R2-3C1-6+3;R2-3C6+2;"
  
  treePat = "(([RC][0-9]*[,-]?[0-9]*)*[+][0-9]*;)"
  rangePat = "([RC][0-9]*[-][0-9]*)"
  nodePat = "([RC][0-9,-]*)"
  
  breakIntoInputTrees x = endBy ";" x
  breakIntoInputNodes x = getAllTextMatches $ x =~ nodePat :: [String]
  
  data NodeContent = NodeContent { idy::Char, vals::[Int] } deriving (Show)
  data Tree = Node { content::NodeContent, children::[Tree]} deriving (Show)
  data GridMod = GridMod { rows::[Int], cols::[Int], mod::[Int] } deriving (Show)
  data Path = Path { pathSum::Int, corner::[Char] } deriving (Show, Eq, Ord)
  
  go = printCornerNames $ maxOfMinPaths (maxOfMinValues 0 listOfMinPaths) listOfMinPaths
  
  printCornerNames pathList = putStrLn $ unwords [ corner path | path &lt;- pathList ]
  
  maxOfMinPaths max [] = []
  maxOfMinPaths max (h:t) = if (pathSum h == max) 
                              then h:maxOfMinPaths max t
                              else maxOfMinPaths max t
  
  maxOfMinValues max [] = max
  maxOfMinValues max (h:t) = if (pathSum h &gt; max) 
                              then maxOfMinValues (pathSum h) t 
                              else maxOfMinValues max t 
  
  listOfMinPaths = findMinimums finalArray
  
  findMinimums array = [quadMinPath array center 0 rMod cMod | rMod &lt;- [-1,1], cMod &lt;- [-1,1]] 
  
  quadMinPath array (r,c) sum rMod cMod
      | isCorner (r,c)    = Path (sum + (posVal array r c)) (cornerName (r,c))
      | otherwise         = decidePaths array (r,c) sum rMod cMod
  
  decidePaths array (r,c) sum rMod cMod
      | (validRow (r + rMod) &amp;&amp; validCol (c + cMod)) =
          minimum     [   
                          quadMinPath array (r + rMod, c) (sum + (posVal array r c)) rMod cMod,
                          quadMinPath array (r, c + cMod) (sum + (posVal array r c)) rMod cMod
                      ]
      | (validRow (r + rMod)) = quadMinPath array (r + rMod, c) (sum + (posVal array r c)) rMod cMod
      | otherwise = quadMinPath array (r, c + cMod) (sum + (posVal array r c)) rMod cMod
  
  posVal array r c = array !! (toIndex r c)
  
  isCorner x = elem x [(1,1), (1,cMax), (rMax,1), (rMax,cMax)]
  
  cornerName x    | x == (1,1) = "TOP-LEFT" | x == (1,cMax) = "TOP-RIGHT" 
                  | x == (rMax,1) = "BOTTOM-LEFT" | x == (rMax,cMax) = "BOTTOM-RIGHT"
  
  validRow r = if (r &gt;= 1 &amp;&amp; r &lt;= rMax) then True else False
  validCol c = if (c &gt;= 1 &amp;&amp; c &lt;= cMax) then True else False
  
  rMax = fst findMaximums
  cMax = snd findMaximums
  
  center = (quot (fst findMaximums) 2 + 1, quot (snd findMaximums) 2 + 1)
  
  finalArray = modifyArray (createArray findMaximums) (toModifiers createGridModders)
  
  modifyArray array [] = array
  modifyArray array ((r,c,m):t) = modifyArray (addToArray array (toIndex r c) m) t
  
  addToArray array index mod = (take index array) ++ [(mod + array !! index)] ++ (drop (index + 1) array)
  
  toIndex r c = (r - 1) * (snd findMaximums) + c - 1
  
  createArray (maxR,maxC) = (take (maxR * maxC)) (repeat 0)
  
  printArray array =  mapM_ putStrLn [ printRow row | row &lt;- (chunksOf (snd findMaximums) array)]
  printRow row = unwords (map show row)
  
  toModifiers gridModders = flat [ toModifier gw | gw &lt;- gridModders ]
  
  toModifier (GridMod r c m) = [ (x,y,head m) | x &lt;- r, y &lt;- c]
  
  createGridModders = adjustForMaximums (treeWalk (GridMod [] [] []) buildAllTrees)
  
  adjustForMaximums gridMods = [ fillMax gm findMaximums | gm &lt;- gridMods ] 
  
  fillMax (GridMod [] [] m) (maxR,maxC) = (GridMod [1..maxR] [1..maxC] m)
  fillMax (GridMod [] c m) (maxR,maxC) = (GridMod [1..maxR] c m)
  fillMax (GridMod r [] m) (maxR,maxC) = (GridMod r [1..maxC] m)
  fillMax (GridMod r c m) (maxR,maxC) = (GridMod r c m)
  
  treeWalk (GridMod r c m) (Node (NodeContent 'R' v) []) = [(GridMod v c m)]
  treeWalk (GridMod r c m) (Node (NodeContent 'C' v) []) = [(GridMod r v m)]
  treeWalk (GridMod r c m) (Node (NodeContent 'M' v) []) = [(GridMod r c v)]
  treeWalk (GridMod r c m) (Node (NodeContent 'R' v) ch) =  flat [ (treeWalk (GridMod v c m) tree) | tree &lt;- ch ]
  treeWalk (GridMod r c m) (Node (NodeContent 'C' v) ch) =  flat [ (treeWalk (GridMod r v m) tree) | tree &lt;- ch ]
  treeWalk (GridMod r c m) (Node (NodeContent 'M' v) ch) =  flat [ (treeWalk (GridMod r c v) tree) | tree &lt;- ch ]
  treeWalk (GridMod r c m) (Node (NodeContent 'Z' v) ch) =  flat [ (treeWalk (GridMod r c m) tree) | tree &lt;- ch ]
  
  flat [] = []
  flat (h:t) = h ++ flat t
  
  findMaximums = (oddify(findMaxRows buildAllTrees), oddify(findMaxCols buildAllTrees))
  
  oddify num = num + ((Prelude.mod num 2) - 1) * (-1)
  
  findMaxRows (Node (NodeContent 'R' v) []) = maximum v
  findMaxRows (Node (NodeContent _ _) []) = 0
  findMaxRows (Node (NodeContent 'R' v) c) = maximum (v ++ [ findMaxRows x | x &lt;- c ])
  findMaxRows (Node (NodeContent _ _) c) = maximum [ findMaxRows x | x &lt;- c ]
  
  findMaxCols (Node (NodeContent 'C' v) []) = maximum v
  findMaxCols (Node (NodeContent _ _) []) = 0
  findMaxCols (Node (NodeContent 'C' v) c) = maximum (v ++ [ findMaxCols x | x &lt;- c ])
  findMaxCols (Node (NodeContent _ _) c) = maximum [ findMaxCols x | x &lt;- c ]
  
  buildAllTrees = Node (NodeContent 'Z' []) (buildIntoTrees (createNodeContentList))
  
  buildIntoTrees x = [ buildIntoTree treeNodeContentList | treeNodeContentList &lt;- x ]
  
  buildIntoTree (h:t) = Node h [ buildSubTree subList | subList &lt;- (easyList t) ]
  
  buildSubTree (h:t) = Node h [ Node content [] | content &lt;- t ]
  
  easyList nodeContentList = tail (simplifyNodeList (idy (head nodeContentList)) nodeContentList [] [])
  
  simplifyNodeList identity [] fullList nextList = fullList ++ [nextList]
  simplifyNodeList identity (h:t) fullList nextList = if (idy h == identity)
                                                          then simplifyNodeList identity t (fullList ++ [nextList]) [h]
                                                          else simplifyNodeList identity t fullList (nextList ++ [h])
  
  createNodeContentList = [ tupleTreeToNodeContentList tupleTree | tupleTree &lt;- (parseToListOfTupleTrees ex1)]
  
  parseToListOfTupleTrees input = [ toTupleTree x | x &lt;- breakIntoInputTrees input]
  
  toTupleTree x = ('M', [modifier x]):[ createTupleNode y | y &lt;- breakIntoInputNodes x]
  
  modifier x = read (last (splitOn "+" x )) :: Int
  
  createTupleNode nodeStr = (head nodeStr, getNodeNumbers nodeStr)
  
  getNodeNumbers nodeStr = if (nodeStr =~ rangePat :: Bool)
                      then extractRange (onlyNumbers nodeStr)
                      else onlyNumbers nodeStr
  
  onlyNumbers str = toInt (words (replaceNonDigit str))
  
  extractRange numList = [head numList .. last numList]
  
  replaceNonDigit [] = []
  replaceNonDigit ('R':t) = ' ':replaceNonDigit t
  replaceNonDigit ('C':t) = ' ':replaceNonDigit t
  replaceNonDigit ('-':t) = ' ':replaceNonDigit t
  replaceNonDigit (',':t) = ' ':replaceNonDigit t
  replaceNonDigit (h:t) = h:replaceNonDigit t
  
  toInt :: [String] -&gt; [Int]
  toInt = map read
  
  tupleTreeToNodeContentList x = [ tupleNodeToNodeContent tupleNode | tupleNode &lt;- x ]
  
  tupleNodeToNodeContent x = NodeContent (fst x) (snd x)
  </code></pre>