Ответ 1
Разбейте строку и используйте макет:
mynub = unsort
. map head
. groupBy ((==) `on` fst)
. sortBy (comparing fst)
. rememberPosition
(несущественная фоновая информация/мотивация)
Я использовал другую версию nub
, вдохновленную разочарованием в книге Yesod, используя ее.
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) вместо исходного nub O (n 2). Но это не имеет значения. Проблема в том, что так долго! Это действительно не так сложно, но долго (и я один из тех людей, которые ненавидят более 80 столбцов или горизонтальных полос прокрутки на блоках кода StackOverflow).
(вопрос)
Каковы лучшие способы в Haskell для выражения длинных цепей функционального состава, таких как это?
Разбейте строку и используйте макет:
mynub = unsort
. map head
. groupBy ((==) `on` fst)
. sortBy (comparing fst)
. rememberPosition
ширина строки легко решается:)
> 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
> }