tags:

views:

168

answers:

4

I have a function which creates a tuple after computation, but I would like to write it to file.

I know how to write to a file using writeFile, but do not know how to combine the computation and monads IO together in the type signature.

This is my code.

invest :: ([Char]->Int->Int->([Char], Int) ) 
 -> [Char]->Int->Int->([Char], Int)
invest myinvest x y = myinvest x y

myinvest :: [Char]->Int->Int->([Char], Int)
myinvest w x y 
 | y > 0 = (w, x + y)
 | otherwise = error "Invest amount must greater than zero"
 where 

I have a function which computes the maximum value from a list, but I want this function to receive input from a file, and then perform the computation of maximum value.

maximuminvest :: (Ord a) => [a] -> a
maximuminvest [] = error "Empty Invest Amount List"
maximuminvest [x] = x

maximuminvest (x:xs)   
     | x > maxTail = x  
     | otherwise = maxTail  
     where maxTail = maximuminvest xs

Please help. Thanks.

[Edit]

  1. My new question is at below.

The first and second question can be solve through function composition but when i try it say type mismatch.

I have check it but i couldn't find any errors.

invest :: ( [Char]->Int->Int->([Char], Int) ) -> [Char]->Int->Int-> ([Char], Int)
invest theinvest x y = theinvest x y

theinvest :: [Char]->Int->Int-> ([Char], Int)
theinvest w x y | y > 0 = (w, x + y)
                | otherwise = error "Invest amount must greater than zero"

savefile :: ([Char], Int) -> IO()
savefile (x, y) = do
  let name = fst (x, y)
  let temp = snd(x, y)
  let amount = show temp

  writeFile "C:\\Invest.txt" (name ++ " " ++ amount)

test = savefile . theinvest "asd" 1234 234

The error message is

 ERROR - Type error in application
 * Expression : savefile . invest theinvest "234" 234 234 
         Term : invest theinvest "234" 234 234 
         Type : ([Char],Int)
 * Does not match : a -> b

Please help. My return type is ([Char],Int). Why it complaint as a -> b ? Thanks

I solve this using command like savefile (invest theinvest "asd" 12 12) but why the operator doesn;t works ?

  1. My fourth question is i have something like this ["peter","1000","michell","2000","kelly","3000"] and i would like to convert to [("peter",1000),("michell", 2000),("kelly",3000)]

  2. The reading of file content is ok but i want to filter the string and get the number only. For instance, a file that has "peter 100\nasd 200"

I would like to drop the alphabet and remain the integer here. I just want the [100, 200] to be the argument the function.

Please help.

Thanks.

+7  A: 

You might want to do something like

main = do
  c <- computation
  writeFile "filename" (show c)

to write out to the file using a Show instance for the result of the computation. If your types are easy enough, this is both human-readable and readable for Haskell restoring the value again.

For the second question, suppose your file stores values as

[1.5,2.3,5.1,6.3,9.8]

then it is blindingly easy to read them in and perform a computation:

main = do
  str <- readFile "filename"
  return $ computation (read str)

should do it. If instead you have your data with an item per line, or in a CSV file, or something else, it gets a little bit more involved. For CSV there is Text.CSV up on Hackage that seems to do the trick.

Mikael Vejdemo-Johansson
+2  A: 

creates a tuple after computation, but I would like to write it to file.

The simplest way is with 'show', which gives a text-based serialization method for most Haskell data types.

writeFile "foo" (show c)

For more efficient serialization, there is Data.Binary:

encodeFile "foo" c

Which will write it in a binary format.

Don Stewart
I know how to use those method but i solve it using function composition.
peterwkc
Pleas answers my third and fourth question in the first post
peterwkc
+3  A: 

For your question about funcion composition, you have to remember that function application binds very strongly - more strongly than composition. So your problematic expression parses as

savefile . (theinvest "asd" 1234 234)

The type of (theinvest "asd" 1234 234) is ([Char],Int) which is not a function and can't be composed. That's what the type error is about.

You want to apply savefile to this, and the easiest is to just remove the . and put the parentheses in. Another way is to replace the . by $ which is a weakly binding function application operator. And if you really, really want a period in there, you could use (savefile . theinvest "asd" 1234) 234 but that's very silly and unclear, in my opinion.

yatima2975
+1  A: 

for your last question you would use lines to get ["peter 2000", Joe "50"] etc. then use filter to drop non numerics. so

filter Data.Char.isDigit . lines

should do it(Note: code written without being tested may not be 100%, and it doesn't handle the case of "7Bill 400" correctly.)

stonemetal