Haskell: запись результата вычисления в файл - PullRequest
2 голосов
/ 17 июня 2010

У меня есть функция, которая создает кортеж после вычисления, но я хотел бы записать его в файл.

Я знаю, как записать в файл, используя writeFile, но не знаю, как объединить вычисления и монады IO вместе в сигнатуре типа.

Это мой код.

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 

У меня есть функция, которая вычисляет максимальное значение из списка, но я хочу, чтобы эта функция получала входные данные из файла, а затем выполняла вычисление максимального значения.

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

Пожалуйста, помогите. Благодарю.

[Изменить]

  1. Мой новый вопрос ниже.

Первый и второй вопрос можно решить с помощью композиции функций, но когда я пытаюсь это сказать, несоответствие типов.

Я проверил это, но не смог найти никаких ошибок.

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

Сообщение об ошибке

 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

Пожалуйста, помогите. Мой тип возврата - ([Char],Int). Почему это жалоба как a -> b? Спасибо

Я решаю это с помощью команды вроде savefile (invest theinvest "asd" 12 12), но почему оператор не работает?

  1. Мой четвертый вопрос: у меня есть что-то вроде этого ["Питер", "1000", "michell", "2000", "Келли", "3000"], и я хотел бы преобразовать в [(" peter ", 1000), (" michell ", 2000), (" kelly ", 3000)]

  2. Чтение содержимого файла в порядке, но я хочу отфильтровать строку и получить только номер. Например, файл с именем «peter 100 \ nasd 200»

Я хотел бы отбросить алфавит и оставить здесь целое число. Я просто хочу, чтобы [100, 200] был аргументом функции.

Пожалуйста, помогите.

Спасибо.

Ответы [ 4 ]

7 голосов
/ 17 июня 2010

Возможно, вы захотите сделать что-то вроде

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

для записи в файл с использованием экземпляра Show для результата вычисления. Если ваши типы достаточно просты, это удобно для чтения и чтения Хаскеллом, чтобы восстановить значение снова.

Для второго вопроса предположим, что ваш файл хранит значения как

[1.5,2.3,5.1,6.3,9.8]

тогда их легко читать и выполнять вычисления:

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

должен это сделать. Если вместо этого у вас есть данные с элементом в строке, или в CSV-файле, или чем-то еще, они становятся немного более сложными. Для CSV есть Text.CSV на Hackage, который, кажется, делает свое дело.

3 голосов
/ 17 июня 2010

Что касается вашего вопроса о композиции функций, вы должны помнить, что приложение функции связывается очень сильно - сильнее, чем композиция. Таким образом, ваше проблемное выражение анализируется как

savefile . (theinvest "asd" 1234 234)

Тип (theinvest "asd" 1234 234) - это ([Char],Int), который не является функцией и не может быть составлен. Вот в чем ошибка типа.

Вы хотите применить savefile к этому, и самое простое - просто удалить . и вставить скобки. Другой способ - заменить . на $, который является слабой связью приложения оператор. И если вам действительно очень нужен период, вы можете использовать (savefile . theinvest "asd" 1234) 234, но, на мой взгляд, это очень глупо и неясно.

2 голосов
/ 17 июня 2010

создает кортеж после вычисления, но я хотел бы записать его в файл.

Самый простой способ - использовать show, который предоставляет метод сериализации для большинства типов данных Haskell.

writeFile "foo" (show c)

Для более эффективной сериализации есть Data.Binary :

encodeFile "foo" c

Который запишет его в двоичном формате.

1 голос
/ 24 июня 2010

для вашего последнего вопроса вы должны использовать строки, чтобы получить ["peter 2000", Joe "50"] и т. Д., А затем использовать фильтр для удаления нечисловых значений. так что

filter Data.Char.isDigit . lines

должен сделать это (Примечание: код, написанный без проверки, может не быть 100%, и он не обрабатывает случай "7Bill 400" правильно.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...