Выражение длинной цепочки композиций в Хаскеле - PullRequest
11 голосов
/ 20 апреля 2011

(неважная справочная информация / мотивация)

Я реализовывал другую версию nub, вдохновленную книгой Йесода о ее использовании.

map head . group . sort более эффективно, чем вызов nub.Однако в нашем случае порядок важен ...

Поэтому я решил написать "лучший" кусочек, похожий на неважную по порядку версию.И я закончил с этим:

mynub = unsort . map head . groupBy (\x y -> fst x == fst y) . sortBy (comparing fst) . rememberPosition

rememberPosition = flip zip [0..]
unsort = map fst . sortBy (comparing snd)

Это, конечно, делает много дополнительной работы, но это должно быть O (n log n) вместо O оригинального нуба (n 2 ),Но это не относится к делу.Проблема в том, что это так долго !Это действительно не так сложно, но это долго (и я один из тех, кто ненавидит идти шире 80 столбцов или горизонтальных полос прокрутки в блоках кода StackOverflow).

(вопрос)

Каковы лучшие способы в Haskell для выражения длинных цепочек композиции функций, таких как эта?

Ответы [ 2 ]

17 голосов
/ 20 апреля 2011

Разбейте строку и используйте раскладку:

mynub = unsort 
      . map head 
      . groupBy ((==) `on` fst)
      . sortBy (comparing fst) 
      . rememberPosition
8 голосов
/ 20 апреля 2011

ширина строки легко решается:)

> mynub = { unsort 
>         . map head 
>         . groupBy (\x y -> fst x == fst y) 
>         . sortBy (comparing fst) 
>         . rememberPosition
>         }

, но я едва привык читать композицию справа налево.Сверху вниз немного.Мне кажется, что стрелка или (>>>) = flip (.) Приятнее, но я понятия не имею, будет ли это идиоматическим

> mynub = { rememberPosition
>       >>> sortBy (comparing fst) 
>       >>> groupBy (\x y -> fst x == fst y) 
>       >>> map head 
>       >>> unsort 
>         }
...