2014-11-21 2 views
4

Интересно, если можно построить следующие функциямиTraversable к проходимым которым пробросить только элемент с указанным индексом

ix :: (Applicative a, Traversable t) => Int -> (v -> a v) -> (t v -> a (t v)) 

который использует pure для всех элементов, кроме г-го, для которых v -> a v используется (Traversal над значением с указанным индекс).

В основном я пытаюсь обобщить следующую функцию для всех пересечений. Или это невозможно? Traversable всегда может быть преобразован в Zipper, и я думал, что он может быть обобщен.

idx _ _ []  = pure [] 
idx 0 f (x:xs) = (:xs) <$> f x 
idx i f (x:xs) = (x:) <$> idx (i - 1) f xs 
+3

Это делается для смерти в объективе. Стоит строить свои шаги самостоятельно, но вы можете увидеть миллион обобщенных примеров таких вещей. –

ответ

3

Предпринимаемая ad-hoc попытка. Я уверен, что есть более элегантные варианты:

import Control.Applicative 
import Control.Monad.State 
import Data.Traversable as T 

ix :: (Applicative a, Traversable t) => Int -> (v -> a v) -> (t v -> a (t v)) 
ix i f = 
    sequenceA 
    . flip evalState 0 
    . T.mapM (\ x -> do 
        j <- get 
        put (j + 1) 
        if i == j then return (f x) 
           else return (pure x))