Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Общие вопросы по программированию, компьютерный форум
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.12.2012, 10:25   #1
Kostia
Участник клуба
 
Аватар для Kostia
 
Регистрация: 21.11.2007
Сообщений: 1,690
По умолчанию Haskell IO чистота чистотой, но ...

Вчера я спокойно пропсиховался во время написания некоторых программ на Haskell. Проблема с которой столкнулся, это использование результатов работы не чистых функций и процедур в этом чистом языке.
Задачи, которые я решал были чрезвычайно просты, это было вычисление факториала, чисел фибоначчи ... Но когда потребовалось реализовать ввод данных с клавиатуры, последовательность случайных чисел которая генерится не от константы, а от функции времени. В общем потерял пару нервных клеток, осталось совсем еще много.
В общем вот код:

Код:
import System
import Random
import IO
import Time

--Для того чтобы при каждом запуске генерилась новая последовательно псевдослучайных чисел
makeTime :: CalendarTime -> Int
makeTime calendar = fromIntegral (ctPicosec calendar)

main = do   tm <- (getClockTime >>= toCalendarTime)
            result (vMonte (makeTime tm)) vCilin

--методом Монте-Карло вычисляем объём цилиндра (5 10) в кубе 10x10x10
vMonte r = volumeMonteCarlo 1000 r (inCilinder 5 10) * 10 * 10 * 10
--результат точного метода
vCilin = volCilinder 5 10
--результат
result a b = do print a
                print b
                print (1 - a / b)
--функция проверка попадания точки внутрь цилиндра
inCilinder r h x y z =  ((x*x + y*y) <= (r*r)) && (abs z < h/2)
--точный метод объёма цилиндра
volCilinder r h = pi*r*r*h

--списко случайных чисел
srand r = randomRs (-5, 5) (mkStdGen r) :: [Double]

--вычисление объёма фигуры методом Монте-Карло
volumeMonteCarlo n r fn = (volumeMonteCarlo' (take (n * 3) (srand r)) fn 0) / fromIntegral n
volumeMonteCarlo' [] fn i = i
volumeMonteCarlo' (x:y:z:s) fn i | fn x y z == False = volumeMonteCarlo' s fn i
                                 | otherwise = volumeMonteCarlo' s fn (i + 1)
Интересует вопрос, можно ли более красиво обруливать функции с побочными эффектами, чем это сделано у меня? И просьба в целом оценить код и высказать замечания.
Kostia вне форума Ответить с цитированием
Старый 07.12.2012, 08:47   #2
the_deer_one
Участник клуба
 
Аватар для the_deer_one
 
Регистрация: 04.04.2010
Сообщений: 1,554
По умолчанию

А в чём ваще проблема то?
the_deer_one вне форума Ответить с цитированием
Старый 07.12.2012, 14:30   #3
Kostia
Участник клуба
 
Аватар для Kostia
 
Регистрация: 21.11.2007
Сообщений: 1,690
По умолчанию

Проблема в том, что я не могу просто написать:
Код:
rand = srand (makeTime t) 
    where t = getClockTime >>= toCalendarTime
Цитата:
Couldn't match expected type `CalendarTime'
with actual type `IO CalendarTime'
а так могу:
Код:
main = do   tm <- (getClockTime >>= toCalendarTime)
            result (vMonte (makeTime tm)) vCilin
Но рабочий способ часто крайне не удобен и приходится извращаться
Kostia вне форума Ответить с цитированием
Старый 07.12.2012, 15:41   #4
the_deer_one
Участник клуба
 
Аватар для the_deer_one
 
Регистрация: 04.04.2010
Сообщений: 1,554
По умолчанию

Почему в не функциональных языках таких проблем не возникает. Это плохо?
the_deer_one вне форума Ответить с цитированием
Старый 07.12.2012, 18:57   #5
Kostia
Участник клуба
 
Аватар для Kostia
 
Регистрация: 21.11.2007
Сообщений: 1,690
По умолчанию

Цитата:
Почему в не функциональных языках таких проблем не возникает. Это плохо?
Еще как плохо =)
Функция на одни и те же входные данные должна возвращать один и тот же результат. В случае с getClockTime такого не происходит, параметров у нее вообще нет, а результат всегда разный. Поэтому с такими функция особое обращение по средством специального класса IO. Но IO Integer != Integer, хотя можно и написать:
Код:
toInteger :: IO Integer -> Integer
toInteger = read
Но функции read, show ... определены далеко не у всех и часто их не получается использовать как этого хотелось бы.
Почему это плохо? Просто если принять это ограничение, на счет однозначном соответствии входных и выходных параметрах, то можно воротить просто невероятные фишки(под впечатлением (= ), которых в классических языках нет, а их реализация будет выражена в сотнях строк кода. Ну например такая конструкция: g (Y g)
Подробнее тут
Достаточно просто реализовать автоматическое распараллеливание выполнения функций, ведь переменных нет, есть только разовые объекты, которые единожды вычисляются и больше не меняются, ну и еще есть константы. Поэтому многое становится явным и переменные это зло xD, шутка.
Понравились вот эти лекции, собственно с них и начал.
Еще понравилась книжка "Душкин Р. В. функциональное программирование на языке Haskell", но начать с нее программировать не получилось.
Также в скором времени ожидаю приход "Изучай Haskell во имя добра!", по отзывам вроде самое оно.

Последний раз редактировалось Kostia; 07.12.2012 в 19:06.
Kostia вне форума Ответить с цитированием
Старый 07.12.2012, 19:22   #6
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Цитата:
Почему в не функциональных языках таких проблем не возникает. Это плохо?
Вы зря стебаетесь, в последнее время императивные языки развиваются за счет воровства фишек функционального программирования. И эти Ваши мегапопулярные и то на чем Вы сидите - с++ и c# понатырели и оттуда идеи.
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 07.12.2012, 21:29   #7
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

Можно main так переписать (если Вы об этом):
Код:
main = getClockTime >>= toCalendarTime >>= (buildResult . vMonte . makeTime)
  where buildResult r = result r vCilin
Любой код в do-нотации - это просто синтаксический сахар над последовательностью вызова оператора связывания (>>=)
netrino вне форума Ответить с цитированием
Старый 11.12.2012, 19:17   #8
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Цитата:
На мой взгляд, все ФЯП - для ЧСВ, в основном.
Ага, Лисп в Автокаде и гимпе исключительно для поднятия чсв юзеров, котрые об этом как правило и не знают.
Цитата:
Вон на Лурке: кричали какое гумно PHP, щас мы все на Erlang перепишем.
PHP от этого лучше не становится.
Цитата:
Переписали. Теперь страницы грузятся черте-как, если низкая скорость, загружается только кусок страницы.
Даже этот форум грузится иногда черте-как.
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 12.12.2012, 08:14   #9
the_deer_one
Участник клуба
 
Аватар для the_deer_one
 
Регистрация: 04.04.2010
Сообщений: 1,554
По умолчанию

Utkin
Цитата:
Вы зря стебаетесь, в последнее время императивные языки развиваются за счет воровства фишек функционального программирования.
Да ну, и какие же фишки были украдены?
the_deer_one вне форума Ответить с цитированием
Старый 12.12.2012, 08:47   #10
Kostia
Участник клуба
 
Аватар для Kostia
 
Регистрация: 21.11.2007
Сообщений: 1,690
По умолчанию

Цитата:
Да ну, и какие же фишки были украдены?
Лямбда функции как минимум =)
Упрощение рапараллеливания std::async
Т.к. параллелить приложение написанное в функциональном стиле, очень просто, с этим даже компилятор может справиться, то императивные языки наращивают свои библиотеки для программирования в функциональном стиле. (достаточно много нового в <functional> в c++11 появилось)
А также расширение в области метапрограммирования и улучшения шаблонов, что привело к появления подобия сопоставления с образцом, вычислению типа возвращаемого значения по типам входных параметров и т.д.
В C# есть делигаты, (IMHO) но попахивает функциональщиной xD
Kostia вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Нужна по haskell KatrinOops Помощь студентам 0 28.05.2012 14:38
С++ & Haskell XZentus Свободное общение 0 24.03.2011 21:44
Абстрагирование списков на Haskell Lakiii Помощь студентам 0 17.12.2009 15:00
Haskell Katech Свободное общение 5 12.07.2009 23:40
Haskell Анастасия52 Помощь студентам 0 05.05.2009 14:09