Читаю тут книгу по хаскелю. соответственно все новое пытаюсь сразу наложить на нужную мне задачу. Задача такова:
коммуникационный сервер, с какой то периодичностью по очереди по одному сом порту читает два прибора.
прочитанную информацию с этих приборов нужно к примеру записать в файл с меткой времени когда мы прочитали.
и так по циклу...
как тут наложить функциональное?
то есть к примеру фунция записи в файл. параметром получает какую то структуру данных с прибора. эта структура получает параметром прибор который ей надо читать с какой то периодичностью.
но. а если вызовется запись в файл сразу с одного прибора и со второго? а одновременно читать приборы нельзя. можно только по очереди...
а таких сом портов (потоков) может быть несколько...
и на каждом разное количество приборов.
и все надо сохранить в файл как можно быстрее и читать как можно чаще одни типы данных, другие с жестко заданной периодичностью итд.
в общем я в шоке
может ли ктото мне немного разжевать саму идеологию применения функционального языка в таких задач? понятно что есть erlang — но по нему у меня книги нет. а что он что haskel по сути своей функциональные. и после того как пойму общую идеологию. потом смогу ее натянуть на любой функциональный язык..
I>может ли ктото мне немного разжевать саму идеологию применения функционального языка в таких задач?
скжем так — нет какой-то общей идеологии функциональных или ООП языков, но есть фактические отличия нынешгих популярных языков (C, Java...) от Haskell и Erlang. вот те из них, которые будут иметь значение для этой задачи:
— автоматический вывод типов
— клозуры, т.е. возможность передать любое действие в качестве параметра процедуре
— неизменяемые данные и основанный на этом механизм взаимодействия тредов
реализация твоей задачи может выглядеть примерно так:
main = do com <- replicateM 4 newMVar -- создаём 4 мьютекса для синхронизации работы с 4 компортами
files <- mapM ((`fileOpen` WriteMode).show) [0..9] -- создаём файлы с именами "0".."9" для записи данных
mapM_ (forkIO$ service com files)
[ (0, 0x48, 100, 0) -- список (номер ком-порта, адрес Modbus, частота сканирования, номер файла),
, (0, 0x88, 0, 1) -- описывающий откуда и с какой частотой читать данные и куда их записывать
...]
service com files (port, addr, delay, filenum) = do
x <- withMVar (com!port) $ do -- блокируем доступ других потоков к этому ком-порту
... -- читаем данные из ком-порта
hPutStrLn (files!filenum) x -- записываем данные в файл
wait delay -- ожидаем заданное число микросекунд
service com (port, addr, delay, filenum) -- рекурсия используется для организации бесконечного цикла
за исключением функций работы с ком-портом и реализации протокола обмена, это полная реализация
Здравствуйте, BulatZiganshin, Вы писали:
I>>может ли ктото мне немного разжевать саму идеологию применения функционального языка в таких задач?
BZ>скжем так — нет какой-то общей идеологии функциональных или ООП языков, но есть фактические отличия нынешгих популярных языков (C, Java...) от Haskell и Erlang. вот те из них, которые будут иметь значение для этой задачи:
если често то просто обалдел так мало строк
Здравствуйте, ironwit, Вы писали:
I>Читаю тут книгу по хаскелю. соответственно все новое пытаюсь сразу наложить на нужную мне задачу. Задача такова: I>коммуникационный сервер, с какой то периодичностью по очереди по одному сом порту читает два прибора. I>прочитанную информацию с этих приборов нужно к примеру записать в файл с меткой времени когда мы прочитали. I>и так по циклу...
I>как тут наложить функциональное?
Проблема, пнимаешь . Не ту книгу читаешь. Для твоей задачи надо читать книгу по Эрлангу.
Здравствуйте, Gaperton, Вы писали:
G>Здравствуйте, ironwit, Вы писали:
I>>Читаю тут книгу по хаскелю. соответственно все новое пытаюсь сразу наложить на нужную мне задачу. Задача такова: I>>коммуникационный сервер, с какой то периодичностью по очереди по одному сом порту читает два прибора. I>>прочитанную информацию с этих приборов нужно к примеру записать в файл с меткой времени когда мы прочитали. I>>и так по циклу...
I>>как тут наложить функциональное?
G>Проблема, пнимаешь . Не ту книгу читаешь. Для твоей задачи надо читать книгу по Эрлангу.
давай русскую книгу по ерлангу или англ но простую. там вообще книга по обучению студентов функциональщине на haskel
G>И все. В Хаскеле то же самое можно устроить через ленивые списки и бесконечно-рекурсиные функции ("потоки", они же streams)
ты на нём не работал, видимо — ленивые списки должны вычисляться без использования побочных эффектов. так что решение на хаскеле точно такое же, как и на эрланге
Здравствуйте, BulatZiganshin, Вы писали:
G>>И все. В Хаскеле то же самое можно устроить через ленивые списки и бесконечно-рекурсиные функции ("потоки", они же streams)
BZ>ты на нём не работал, видимо — ленивые списки должны вычисляться без использования побочных эффектов. так что решение на хаскеле точно такое же, как и на эрланге
Видимо, ты не применял технику декомпозицию через потоки (ленивые списки), на которой в частности у нас строятся все модели харда на Хаскле. Тебе никто не мешает внутри бесконечно-рекурсивной функции "принимающей и отправляющей" данные через потоки поставить unsafePerformIO. Это совершенно безопасно — если иметь в виду семантику, что эти функции работают как бы параллельно.
я сам от него балдею тут, как видишь, ничего лишнего — только голое описание алгоритма и данные о наблюдаемых портах. в обычных языках приходится писать много лишних буков из-за их меньшей выразительной мощности
вообще-то говоря, самым главным языком для программистов является английский, но тем не менее:
Здравствуйте, BulatZiganshin, Вы писали:
BZ>ты на нём не работал, видимо — ленивые списки должны вычисляться без использования побочных эффектов. так что решение на хаскеле точно такое же, как и на эрланге
Да ну, вспомни диалоги, да и никто не мешает завернуть всё это дело в IO.
Здравствуйте, lomeo, Вы писали:
L>Здравствуйте, BulatZiganshin, Вы писали:
BZ>>ты на нём не работал, видимо — ленивые списки должны вычисляться без использования побочных эффектов. так что решение на хаскеле точно такое же, как и на эрланге
L>Да ну, вспомни диалоги, да и никто не мешает завернуть всё это дело в IO.
я говаорю не о всяких теоретичсеких возможностях, а о том, как это надо программировать, тем более начинающему. и ленивые вычисления здесь не подойдут ввиду императивности выполняемых действий
Здравствуйте, BulatZiganshin, Вы писали:
BZ>>вообще-то говоря, самым главным языком для программистов является английский, но тем не менее:
BZ>и наше всё : http://www.haskell.org/bz/FreeArc-sources.tar.gz
G>Видимо, ты не применял технику декомпозицию через потоки (ленивые списки), на которой в частности у нас строятся все модели харда на Хаскле. Тебе никто не мешает внутри бесконечно-рекурсивной функции "принимающей и отправляющей" данные через потоки поставить unsafePerformIO. Это совершенно безопасно — если иметь в виду семантику, что эти функции работают как бы параллельно.
Это делать нельзя в общем случае (например, чтение из одного файла).
То, как делать можно, описано в описании Fudgets.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Здравствуйте, thesz, Вы писали:
G>>Видимо, ты не применял технику декомпозицию через потоки (ленивые списки), на которой в частности у нас строятся все модели харда на Хаскле. Тебе никто не мешает внутри бесконечно-рекурсивной функции "принимающей и отправляющей" данные через потоки поставить unsafePerformIO. Это совершенно безопасно — если иметь в виду семантику, что эти функции работают как бы параллельно.
T>Это делать нельзя в общем случае (например, чтение из одного файла).
Что, даже читать из одного файла нельзя? Это довольно странно. И что будет, если все-таки прочитать? Может, ты имел в виду, что туда нельзя писать из разных?
Здравствуйте, Gaperton, Вы писали:
G>Здравствуйте, thesz, Вы писали:
G>>>Видимо, ты не применял технику декомпозицию через потоки (ленивые списки), на которой в частности у нас строятся все модели харда на Хаскле. Тебе никто не мешает внутри бесконечно-рекурсивной функции "принимающей и отправляющей" данные через потоки поставить unsafePerformIO. Это совершенно безопасно — если иметь в виду семантику, что эти функции работают как бы параллельно.
T>>Это делать нельзя в общем случае (например, чтение из одного файла).
G>Что, даже читать из одного файла нельзя? Это довольно странно. И что будет, если все-таки прочитать? Может, ты имел в виду, что туда нельзя писать из разных?
во-первых, указатель текущей позиции один на всех, во-вторых, нет гарантий атоммарности операции. на практике например putStrLn, реализованный как два putStr, ведёт себя очень забавно при вызове в параллельных тредах