LINUX.ORG.RU

[ФП] пример работы с файлами?


0

0

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

Я уверен, что ФП-ники с этим не согласны, но не видел примеров, собственно, программ. Кто-нибудь может дать ссылку на или написать коротенькую программу на любом функциональном ЯП на базовую работу с файлами (типа: вывести в файл abc.dat список всех файлов в текущем каталоге, имя которых заканчивается на '.so'). Желательно, с обработкой ошибок.

Спасибо.

★★★★
#!/usr/bin/perl
use warnings;
use strict;

open LIST,">","abc.dat" or die "abc.dat: $!\n";
for (glob "*.so") {
print LIST "$_\n";
}
close LIST or die "abc.dat: $!\n";

В случае юникодных имён файлов может ругаться на wide charachter in print, это не смертельно и лечится open LIST,«>:utf8»,«abc.dat».

AITap ★★★★★
()

вывести в файл abc.dat список всех файлов в текущем каталоге, имя которых заканчивается на '.so'

бугага.

 ls | grep \.so$ | sort > abc.dat [\code]

и скажи еще что это не функционально ;) 
Rastafarra ★★★★
()
Ответ на: комментарий от jtootf

Глупость функциональщиков, да? На поцвставленный вопрос то никто конкретно не ответил. Где код на какацкеле, который был бы короче вышеприведенного императивного кода на bash?!?

anonymous
()
Ответ на: комментарий от AITap

Перл - не функциональный язык.

JackYF ★★★★
() автор топика
Ответ на: комментарий от anonymous

короче вышеприведенного императивного кода на bash

В каком месте он на bash? ls, grep и sort уже стали командами bash?

GotF ★★★★★
()
Ответ на: комментарий от jtootf

>http://book.realworldhaskell.org/read/systems-programming-in-haskell.html

Много букв, в середине есть большой исходник с IO, почти без обработки ошибок.

http://www.haskell.org/haskellwiki/Tutorials/Programming_Haskell/String_IO


Обработки ошибок нет совсем.

http://www.haskell.org/tutorial/io.html


Здесь, по большому счёту, тоже.

Как видишь, из чуть более, чем до фига примеров очень непросто найти то, что нужно.

JackYF ★★★★
() автор топика
Ответ на: комментарий от Rastafarra

>покажи, где там императивщина?

Я просил программу на ФП. Ты мне привёл вызов императивных программ из императивного языка.

JackYF ★★★★
() автор топика
Ответ на: комментарий от GotF

>В каком месте он на bash?

От баша здесь разрыв строки в качестве управляющего символа )

annulen ★★★★★
()
Ответ на: комментарий от jtootf

>раздел 7.3, не?

Мм, да, в конце раздела теперь заметил. Но: что напечает строка

catch getLine" (\err -> return («Error: » ++ show err))

если, скажем, read(2) свалится с EIO? Или EINTR? Это мне интереснее всего.

JackYF ★★★★
() автор топика
Ответ на: комментарий от Rastafarra

>> вызов _императивных_ _программ _

wtf??? :)


Программ, написанных на императивных языках. Self-fix.

JackYF ★★★★
() автор топика
Ответ на: комментарий от anonymous

>main = (readFile «input.txt» >>= writeFile «output.txt») `catch` (\_ -> print «wtf?»)

Обработка ошибок включает в себя вывод человекочитаемой (или хотя бы машиночитаемой) информации, при работе с каким файлом произошла ошибка и какая именно ошибка.

JackYF ★★★★
() автор топика
import System.Directory import Data.List

main = getDirectoryContents "." >>= writeFile "abc.dat" . unlines . filter (\a -> ".so" `isSuffixOf` a)

без обработки ошибок

unC0Rr ★★★★★
()
Ответ на: комментарий от anonymous

>[code]main = (readFile «input.txt» >>= writeFile «output.txt») `catch` print[/code]

Гм, что напечает эта программа, если input.txt запрещён для чтения?

JackYF ★★★★
() автор топика
Ответ на: комментарий от Waterlaz

>Ну... а вот пиведеный код весьма функционален =)

Ну, всё же не Bash меня сейчас интересует :)

JackYF ★★★★
() автор топика
Ответ на: комментарий от JackYF

[code]main = (readFile «input.txt» >>= writeFile «output.txt») `catch` print[/code]

Гм, что напечает эта программа, если input.txt запрещён для чтения?

Что-то в духе..

$ runhaskell tst.hs
input.txt: openFile: permission denied (Permission denied)
Waterlaz ★★★★★
()
Ответ на: комментарий от JackYF

Гм, что напечает эта программа, если input.txt запрещён для чтения?

input.txt: openFile: permission denied (Permission denied)
unC0Rr ★★★★★
()
Ответ на: комментарий от Waterlaz

> input.txt: openFile: permission denied (Permission denied)

О! Вот это то, что я хотел увидеть.

Открытым остаётся вопрос организации более сложной обработки (допустим, мы делаем fork(), и на EAGAIN нужно не закрыться с ошибкой, а подождать 5 секунд и попробовать ещё раз), но общая картина прояснилась, спасибо приславшим свои варианты.

JackYF ★★★★
() автор топика
Ответ на: комментарий от Rastafarra

Это ты ненормальный. Есть сайд-эффект, устанавливается значение переменной окружения «$?».

anonymous
()
Ответ на: комментарий от anonymous

>в очередной раз сливает даже перлу с башем

Не согласен. В приведённом реешнии «import"ы сойдут за пропущеный в bash-варианте PATH=, отсутствие которого в скрипте можно считать четвёртой ошибкой. Лямбда там не нужна, можно «... filter (isSuffixOf ».so")», т.ч. если дождёмся исправленого башевского варианта, он может оказаться не сильно лучшим.

DonkeyHot ★★★★★
()
Ответ на: комментарий от anonymous

> Есть сайд-эффект

ну... без них даже IO не работает, да? :)

Rastafarra ★★★★
()
Ответ на: комментарий от Rastafarra

>«у меня все работает»

Эка невидаль. Мои скрипты тоже все в некоторых условиях работают.

DonkeyHot ★★★★★
()
#!/bin/bash
for i in *.so ; do [[ -f $i ]] && echo "$i" >> abc.dat ; done

не?

pavel38
()
package scalaapp1

import java.io._;

object Main {

  def main(args: Array[String]): Unit = {
    var k = new PrintWriter(new FileOutputStream("abc.dat"))
    
    k.println(
        new File(".").
        listFiles.
        filter({_.isFile}).
        filter({_.getName.toLowerCase.endsWith(".so")}).
        foldLeft("")((A,B)=>A+B+"\n")
      )
    
    k.close()
  }

}

Более функционально на Scala нельзя, потому что без явного close ничего не записывает.

vertexua ★★★★★
()
Ответ на: комментарий от vertexua

Чуть красивее

toFile("abc.dat"){
      new File(".").
      listFiles.
      filter({_.isFile}).
      filter({ _.getName.toLowerCase.endsWith(".so")}).
      foldLeft("")((A,B)=>A+B+"\n")
}

но необходим все тот же костыль

def toFile(s:String)(f: =>String){
    var k = new PrintWriter(new FileOutputStream(s))
    k.println(f)
    k.close()
  }

vertexua ★★★★★
()
Ответ на: комментарий от balodja

Хм, даже в POSIX'е sort без указанных файлов берет ввод из stdin, так что отсутствие - — это не ошибка. Где же тогда третья?

balodja ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.