rapture 10.06.2011 15:32 unknown

-- функция суммирования элементов целочисленного списка.
sumList :: [Integer] → Integer
sumList [] = 0
sumList (x:s) = x + sumList s
Подозрительно — откуда эта хрень знает, что под x понимается первый элемент списка, а под s — остаток? Почему бы не предположить, что такой хренью нельзя сложить [1,1,1] и [1,1,1] и получить [2,2,2]? Хотя тогда конструктор выглядел бы как [[Integer]] → [Integer], наверное... Эта какая-то полная поебень, похожее на вычисление вывода: ты даешь языку два предиката, а он тебе — вывод. Или один предикат и вывод, а он тебе второй...

1. utros 10.06.2011 15:35 Adium

Это хаскель, ёба! Он думает за тебя, а потом ты думаешь, что же всё-таки думает по поводу твоего кода первотег.

2. jtootf 10.06.2011 15:35 galois

(x:s) — это конструктор списка, собирающий его из головы и хвоста, по нему проводится паттерн-матчинг. сложить два списка нельзя хотя бы потому, что функция принимает один список. сложение двух списков будет выглядеть как sumLists = zipWith (+)

3. octocat 10.06.2011 15:39 emacs3F4BD999

"Prelude> :type (:)" — вот отсюда

4. jtootfoctocat /3 10.06.2011 15:40 galois

:i [] тогда уж

5. octocatjtootf /4 10.06.2011 15:41 emacs3F4BD999

Да, это первичней :)

6. rapturejtootf /2 10.06.2011 15:44 unknown

> сложить два списка нельзя хотя бы потому, что функция принимает один список
> Хотя тогда конструктор выглядел бы как [[Integer]] → [Integer],
> сложение двух списков будет выглядеть как sumLists = zipWith (+)
Этот ответ не отвечает на вопрос "почему хаскель делает именнно так, а не этак", потому что вынуждает смотреть логику работы zipWith :)
Иными словами — можно ли sumList (x:s) = x + sumList s на процессоре распаралелить как zipWith[x...k][k...s] ?

7. jtootfrapture /6 10.06.2011 15:53 galois

параллелизация не меняет семантику функции. функция типа (Num a) => [a] → a от разноса по потокам не превратится в функцию типа (Num a) => [a] → [a] → [a]. если вопрос заключается в том, можно ли распараллелить суммирование списка в Haskell, то ответ — да, но автоматически компилятор этого делать не станет (к счастью)

8. rapturejtootf /7 10.06.2011 15:57 unknown

Почему отсутствие автоматического распаралеливания — к счастью?

9. jtootfrapture /8 10.06.2011 16:02 galois

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

10. rapturejtootf /9 10.06.2011 16:10 unknown

т.е. в таком случае при использовании императивного языка (например, с) программист думает, как будут процессором исполняться его инструкции, а как они будут паралелиться — будет думать компилятор, а при использовании функционального (haskell) он сначала думает, как будет язык представлять функциональное описание в обычных императивных инструкциях, а потом уже как эти инструкции будут исполняться процессором, а потом уже как компилятору сказать так, чтобы он императивное представление паралельного выполнения инструкций воспринял на командах функционального представления? Как-то это... странно, я думал, всегда стремятся вынести на плечи компилятор как можно больше.

11. jtootfrapture /10 10.06.2011 16:13 galois

не кури это больше. много тебе gcc по потокам пораскидывает без каких-нибудь pthreads?

12. jtootfrapture /10 10.06.2011 16:23 galois

и ты что, правда не видишь разницы между императивным заданием того, какая инструкция в каком потоке будет выполнена, и декларативным заданием стратегии параллелизации? смотри: http://www.haskell.org/ghc/docs/6.10.2/h... и ещё смотри: http://www.haskell.org/haskellwiki/GHC/D...

13. rapturejtootf /11 10.06.2011 16:23 unknown

Почему сразу потоки? Развороты циклов, if-ов и пр. Хотя, наверное, хаскель тоже это делает, а контроль типов помогает понимать, что именно нужно вернуть и сложить... Хотя интересно будет сравнить поведение, если руки дойдут. http://akoub.narod.ru/funcbook/chapter1/... говорят, что вычисление n'ого ряда фибоначи происходит быстрее, если использовать побочную функцию. Интересно, в данном случае C'шечка оптимизирует во второй вариант или нет.

14. jtootfrapture /13 10.06.2011 16:26 galois

поставь себе ghc-core и посмотри, что именно делает ghc. к параллелизации это, впрочем, отношения не имеет

Do you really want to delete ?