Re[9]: Какой функциональный язык стоит изучать?
От: deniok Россия  
Дата: 18.03.07 08:30
Оценка:
Здравствуйте, Tonal-, Вы писали:
T>Хотя ленивость иногда стоит того!

А в python ленивость — через yield'ы?
Re[9]: Какой функциональный язык стоит изучать?
От: R.K. Украина  
Дата: 18.03.07 09:41
Оценка: +1
Здравствуйте, deniok, Вы писали:

D>Здравствуйте, R.K., Вы писали:


D>Класс. Компрехеншен — сила!


Есть такое.

D>A inits и tails — это будут

D>
D>tails [] = [[]]
D>tails xxs@(x:xs) = xxs:[ys | ys <- tails xs]

-- чуть проще, компрехеншн уже не нужен
tails [] = [[]]
tails xxs@(_:xs) = xxs : tails xs

Еще интересная задача сделать перестановки с учетом повторяющихся элементов. Функция perm' должна принимать на вход список списков, полученных от group(By) и возвращать список пермутаций без повторений. Например:
> perm' $ group "aabc"
["aabc","aacb","abac","abca","acab","acba","baac","baca","bcaa","caab","caba","cbaa"]
You aren't expected to absorb this
Re[10]: Какой функциональный язык стоит изучать?
От: Tonal- Россия www.promsoft.ru
Дата: 18.03.07 10:05
Оценка: 1 (1)
Здравствуйте, deniok, Вы писали:
D>А в python ленивость — через yield'ы?
Типа того.
Через yield'ы — генераторы, а ленивость — через них, т.к. вычисляется не весь список, а только затребованная часть.
... << RSDN@Home 1.2.0 alpha rev. 675>>
Re[10]: Какой функциональный язык стоит изучать?
От: deniok Россия  
Дата: 18.03.07 10:05
Оценка:
Здравствуйте, R.K., Вы писали:

RK>Еще интересная задача сделать перестановки с учетом повторяющихся элементов. Функция perm' должна принимать на вход список списков, полученных от group(By) и возвращать список пермутаций без повторений. Например:

RK>
>> perm' $ group "aabc"
RK>["aabc","aacb","abac","abca","acab","acba","baac","baca","bcaa","caab","caba","cbaa"]
RK>


Не совсем понял про group — это множество всех (не?)упорядоченных подмножеств?
group "ab" даст ["","a","b","ab"]? Или ["","a","b","ab","ba"]?

Вообще решение в лоб — выкинуть повторяющиеся элементы, написав функцию uniq
uniq $ perm "aabc"

но оно, очевидно, не самое эффективное.
Вечером подумаю.
Re[11]: Какой функциональный язык стоит изучать?
От: R.K. Украина  
Дата: 18.03.07 10:19
Оценка:
Здравствуйте, deniok, Вы писали:

D>Не совсем понял про group — это множество всех (не?)упорядоченных подмножеств?

D>group "ab" даст ["","a","b","ab"]? Или ["","a","b","ab","ba"]?

inits, tails, group — все из модуля List. group выделяет соседние повторяющиеся элементы:
> group "aabc"
["aa","b","c"]
> :t group
group :: (Eq a) => [a] -> [[a]]
-- groupBy аналогична sortBy
> :t groupBy
groupBy :: (a -> a -> Bool) -> [a] -> [[a]]

D>Вообще решение в лоб — выкинуть повторяющиеся элементы, написав функцию uniq
D>
D>uniq $ perm "aabc"
D>

Ага, и такая функция уже есть в List: nub

D>но оно, очевидно, не самое эффективное.
You aren't expected to absorb this
Re[12]: Какой функциональный язык стоит изучать?
От: deniok Россия  
Дата: 18.03.07 20:43
Оценка:
Здравствуйте, R.K., Вы писали:

RK>inits, tails, group — все из модуля List. group выделяет соседние повторяющиеся элементы:

RK>Ага, и такая функция уже есть в List: nub

Ну серый я, как штаны пожарника. Мне казалось, что там из "разумного" только sort и zipы с большими номерами
Re[10]: Какой функциональный язык стоит изучать?
От: dr.Chaos Россия Украшения HandMade
Дата: 21.03.07 11:40
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Cyberax, Вы писали:


C>>Причем, почему-то схемисты и лисповоды — самые ярые противники XML.


А>Так понятно почему. Из-за синтаксического оверхеда.


А>
А>(+ a b)
А>

А>vs.
А>
А><plus>
А>    <a />
А>    <b />
А></plus>

А>


Наверно жутко мучаешься когда вместо инфиксной записи операторов пишешь название функции перед списком аргументов (func x1 x2 x3)?
Побеждающий других — силен,
Побеждающий себя — Могущественен.
Лао Цзы
Re[11]: Какой функциональный язык стоит изучать?
От: Аноним  
Дата: 21.03.07 14:14
Оценка:
Здравствуйте, dr.Chaos, Вы писали:


DC>Наверно жутко мучаешься когда вместо инфиксной записи операторов пишешь название функции перед списком аргументов (func x1 x2 x3)?


Да какие, блин, еще мучения. Что там такого мучительного-то?
Вообще же, хочу сказать, operator precedence parser — это максимум 10 строчек в виде макро и любые операторы с любыми приоритетами в результате, в отличие от "обычных" языков.
Только, разумеется, после некоторой практики, потребность в этом сама отпадает.
Во-первых, более-менее серьезное программирование — это не простые арифметические выражения и циклы. Это коллекции и их трансформации.
Ну типа возможность писать так ценнее всяких приоритетов:
> (map + '(1 2 3) '(4 5 6))
(5 7 9)

Ну и, конечно, префиксность любых функций позволяет разные мелкие вольности типа:
> (+ 1 2 3 4 5)
15


Примеры, для простоты, на Scheme
Re[12]: Какой функциональный язык стоит изучать?
От: dr.Chaos Россия Украшения HandMade
Дата: 21.03.07 14:19
Оценка:
Здравствуйте, Аноним, Вы писали:

И чему тогда ты возражал?
Я просто хотел сказать, что оператор — это та же функция.

Ладно проехали.
Побеждающий других — силен,
Побеждающий себя — Могущественен.
Лао Цзы
Re[11]: Какой функциональный язык стоит изучать?
От: R.K. Украина  
Дата: 01.04.07 18:50
Оценка: 16 (1)
Здравствуйте, deniok, Вы писали:

D>Вообще решение в лоб — выкинуть повторяющиеся элементы, написав функцию uniq

D>
D>uniq $ perm "aabc"
D>

D>но оно, очевидно, не самое эффективное.
D>Вечером подумаю.

Вечер — понятие сильно растяжимое. Такой день сегодня хороший. Выложу-ка я свое решение ниже.
Между прочим, задача очень практическая и нижепоследующая функция, только модифицированная для выдачи дерева Data.Tree вместо вложенных списков, крутится в моем решении Rectangle Strip Packing Problem.

-- perm' принимает список после group(By)
perm' [] = [[]]
perm' xs = intern' xs
    where
    intern' = concatMap (uncurry intern) . splits'
    intern [] [[q]] = [[q]]
    intern ps ((q:qs'):qs) = map (q:) $ intern' $ (ps++) $ case qs' of
        [] -> qs
        _ -> qs':qs

-- splits' это splits без последнего элемента
splits' xs@[_] = [([], xs)]
splits' xxs@(x:xs) = ([], xxs) : [(x:ps, qs) | (ps,qs) <- splits' xs]
You aren't expected to absorb this
Re[12]: Какой функциональный язык стоит изучать?
От: deniok Россия  
Дата: 01.04.07 21:52
Оценка:
Здравствуйте, R.K., Вы писали:


RK>Вечер — понятие сильно растяжимое.



RK>
RK>-- perm' принимает список после group(By)
RK>perm' [] = [[]]
RK>perm' xs = intern' xs
RK>    where
RK>    intern' = concatMap (uncurry intern) . splits'
RK>    intern [] [[q]] = [[q]]
RK>    intern ps ((q:qs'):qs) = map (q:) $ intern' $ (ps++) $ case qs' of
RK>        [] -> qs
RK>        _ -> qs':qs

RK>-- splits' это splits без последнего элемента
RK>splits' xs@[_] = [([], xs)]
RK>splits' xxs@(x:xs) = ([], xxs) : [(x:ps, qs) | (ps,qs) <- splits' xs]
RK>


Вроде понял. intern, приняв, скажем ["a","b"] ["cc","d"], отщепляет первую c и гонит в начало, а остальное собираем в список и снова intern'. Назвать бы их (intern и intern') по-человечески. Вообще, механизм немного похож на мою версию permutations, которая с фильтрами. Там, где у меня была фильтрация, здесь — пересборка списка без q.

А splits' без последнего элемента — это чтобы в intern' образец ((q:qs'):qs) был неопровержим.
Re[13]: Какой функциональный язык стоит изучать?
От: R.K. Украина  
Дата: 02.04.07 15:17
Оценка: +1
Здравствуйте, deniok, Вы писали:

D>Вроде понял. intern, приняв, скажем ["a","b"] ["cc","d"], отщепляет первую c и гонит в начало, а остальное собираем в список и снова intern'. Назвать бы их (intern и intern') по-человечески. Вообще, механизм немного похож на мою версию permutations, которая с фильтрами. Там, где у меня была фильтрация, здесь — пересборка списка без q.


На все имен не напридумываешь. Эти же функции суть просто тело внешней, а имена им даны только для их рекурсивного вызова. Ну с фильтрами таки был лишний прогон с пересозданием списка во внутреннем цикле, а тут просто конкатенация — есть слабая надежда, что компилятор извернется и соптимизирует Еще предикат в фильтре дает совершенно лишнее ограничение на Eq типа элементов списка.

D>А splits' без последнего элемента — это чтобы в intern' образец ((q:qs'):qs) был неопровержим.


Ну да, чтоб лишнего ветвления в паттернах интерн не было.
You aren't expected to absorb this
Re[14]: Какой функциональный язык стоит изучать?
От: deniok Россия  
Дата: 02.04.07 15:39
Оценка:
Здравствуйте, R.K., Вы писали:


RK>На все имен не напридумываешь. Эти же функции суть просто тело внешней, а имена им даны только для их рекурсивного вызова. Ну с фильтрами таки был лишний прогон с пересозданием списка во внутреннем цикле, а тут просто конкатенация — есть слабая надежда, что компилятор извернется и соптимизирует Еще предикат в фильтре дает совершенно лишнее ограничение на Eq типа элементов списка.


Понятно, что с фильтрами алгоритм дурной. Я просто перетаскивал на Хаскелл алгоритм из SICP.
Re: Какой функциональный язык стоит изучать?
От: last shinji  
Дата: 07.04.07 05:01
Оценка:
Почему-то у меня никак не получается понять, как работает функция обращения списка с присаваинванием.
При попытке представить это у меня получается (d c d b c d a b c d), а вовсе не (a b c d).
Возможно я упускаю какую-то деталь, связанную с окружениями, или с тем как представляются списки (как мне показалось, в книге с представлением списков существует некоторый разброд).
Натолкните пожалуйста на верный путь.

(define (mystery x)
  (define (loop x y)
    (if (null? x)
        y
        (let ((temp (cdr x)))
          (set-cdr! x y)
          (loop temp x))))
  (loop x '()))

(define v (list 'a 'b 'c 'd))

(mystery v)
Носок исчез в гильбертовом пространстве. Туда ему и дорога.
Re[2]: Какой функциональный язык стоит изучать?
От: Curufinwe Украина  
Дата: 07.04.07 09:46
Оценка: 2 (1)
Здравствуйте, last shinji, Вы писали:

LS>
LS>(define (mystery x)
LS>  (define (loop x y)
LS>    (if (null? x)
LS>        y
LS>        (let ((temp (cdr x)))
LS>          (set-cdr! x y)
LS>          (loop temp x))))
LS>  (loop x '()))

LS>(define v (list 'a 'b 'c 'd))

LS>(mystery v)
LS>


В каждой итерации берётся голова первого списка и делается головой второго:
(let ((temp (cdr x))) — запоминаем хвост 1 списка
(set-cdr! x y) — голова 1 списка + 2 список
(loop temp x)))) — повторяем итерацию. При первом рекурсивном вызове: temp = (b c d), x = (a), для второго: temp = (c d), x = (b a) и т.д.
Re[3]: Какой функциональный язык стоит изучать?
От: last shinji  
Дата: 07.04.07 12:53
Оценка:
Здравствуйте, Curufinwe, Вы писали:

C>В каждой итерации берётся голова первого списка и делается головой второго:

C>(let ((temp (cdr x))) — запоминаем хвост 1 списка
C> (set-cdr! x y) — голова 1 списка + 2 список
C> (loop temp x)))) — повторяем итерацию. При первом рекурсивном вызове: temp = (b c d), x = (a), для второго: temp = (c d), x = (b a) и т.д.

Спасибо, я невнимательно отнесся к тому, что делает операция set-cdr!.
Носок исчез в гильбертовом пространстве. Туда ему и дорога.
Re[4]: Какой функциональный язык стоит изучать?
От: Partisan  
Дата: 22.04.07 15:20
Оценка:
Во наобсуждали. Зашёл сюда случайно.
Сейчас в магазине есть книжка по Haskell на русском языке:

Душкин Р.В. Функциональное программирование на языке Haskell.


Кроме описания языка, там есть рассуждения о функциональном программировании.
Думаю, изучать ф.п. есть смысл из любопытства, а не в расчёте на последующее практическое
применение, которое было бы авантюрным решением.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.