2017-01-07 2 views
5

Traversable - это в некотором смысле класс контейнеров, структура которых имеет «путь» (который может соответствовать списку), элементы которого могут быть изменены без растворения структуры. Следовательно,Каков самый стандартный/общий способ застегивания прокручиваемого списка?

zipTrav :: Traversable t => t a -> [b] -> Maybe (t (a,b)) 
zipTrav = evalStateT . traverse zp 
where zp a = do 
      bs <- get 
      case bs of 
       [] -> lift Nothing 
       (b:bs') -> put bs' >> return (a,b) 

Однако обход этого списка выглядит немного хакерским и, вероятно, не самым эффективным способом его выполнения. Я бы предположил, что будет стандартная функция, которая выполнила бы вышеупомянутую или более общую задачу, но я не могу понять, что это будет.

ответ

5

Что относительно mapAccumL/mapAccumR?

tzipWith :: Traversable t => (a -> b -> c) -> [a] -> t b -> Maybe (t c) 
tzipWith f xs = sequenceA . snd . mapAccumL pair xs 
    where pair [] y = ([], Nothing) 
      pair (x:xs) y = (xs, Just (f x y)) 

tzip :: Traversable t => [a] -> t b -> Maybe (t (a, b)) 
tzip = tzipWith (,) 

ghci> tzip [1..] [4,5,6] 
Just [(1,4),(2,5),(3,6)] 

ghci> tzip [1,2] [4,5,6] 
Nothing 

К вопросу об эффективности - under the hood в mapAccum функции используют состояние монады, так что все, что я действительно сделал это захватить настоятельную часть вашего кода в функции высшего порядка. Я бы не ожидал, что этот код будет работать лучше вашего. Но я не думаю, что вы можете сделать намного лучше, чем монада State (или ST), учитывая только Traversable t.

+0

@WillNess Nah, вам просто нужно проверить, осталось ли что-либо в списке ввода после того, как вы закончили прохождение. Я обновлю свой код –

+0

@WillNess Я думаю, что вопросник хочет вернуть «Ничего», если в списке недостаточно элементов, чтобы заполнить «Traversable». Идея состоит в том, чтобы сохранить форму «Traversable» при соединении каждого из значений –

+0

ах, это имеет смысл. это означает, что ваша предыдущая версия была действительно правильной. :) Я восстановил вашу предыдущую версию и добавил поясняющий пример. Прошу прощения. –

Смежные вопросы