2017-01-19 69 views
10

Podczas rozważania, jak najlepiej odwzorować, tj. traverse, a -> Maybe a -Kleisli nad unboxed vector, szukałem istniejącej implementacji. Oczywiście U.Vector nie jest Traversable, ale it does supply a mapM, który dla Maybe oczywiście działa dobrze.Dlaczego nie jest możliwe stosowanie tablic próbnych? (Czy tak?)

Ale pytanie brzmi: czy ograniczenie jest naprawdę potrzebne? Cóż, okazuje się, że nawet boxed vectors cheat for the Traversable instance: oni naprawdę tylko przechodzić do listy, które konwersji do/z:

instance Traversable.Traversable Vector where 
    {-# INLINE traverse #-} 
    traverse f xs = Data.Vector.fromList Applicative.<$> Traversable.traverse f (toList xs) 

mono-traversabledoes the same thing also for unboxed vectors; tutaj wydaje się to jeszcze bardziej makabryczne.

Teraz nie byłbym zaskoczony, gdyby vector był w stanie połączyć wiele z tych zhakowanych przejść w znacznie bardziej wydajną formę, ale nadal - wydaje się, że istnieje podstawowy problem, uniemożliwiający nam wykonanie przejścia na tablica od razu. Czy istnieje jakaś "głęboka przyczyna" dla tej niezdolności?

+1

Brak instancji dla 'U.Vector' ma związek z ograniczeniem" Unbox "dla elementów. Zobacz [* Dlaczego tablice unboxed nie są instancjami składanymi? *] (Http://stackoverflow.com/q/36322904/2751851) (odpowiedź, autorstwa Snoymana, zawiera również kilka ważnych komentarzy na temat * mono-traversable *). – duplode

+3

Jasne, ale nie o to pytam. Nie potrzebuję rzeczywistej instancji 'Traversable', potrzebuję tylko wydajnego przejścia! I "mono-traversable" nie oferuje tego. – leftaroundabout

+0

Ups - nie zauważyłem "oczywiście" w twoim pierwszym akapicie :) – duplode

Odpowiedz

2

Po przeczytaniu odpowiedniego źródła vector i próbuje zrobić mapM pracę z Applicative myślę dlaczego Data.Vector.Unboxed.Vector nie posiada funkcji i Data.Vector.Vectortraverse :: (Applicative f, Unbox a, Unbox b) -> (a -> f b) -> Vector a -> f (Vector b) nie posiada natywny traverse jest kod Fusion. Sprawca jest następujący Stream typ:

-- Data/Vector/Fusion/Stream/Monadic.hs Line: 137 

-- | Result of taking a single step in a stream 
data Step s a where 
    Yield :: a -> s -> Step s a 
    Skip :: s -> Step s a 
    Done :: Step s a 

-- | Monadic streams 
data Stream m a = forall s. Stream (s -> m (Step s a)) s 

ta jest używana wewnętrznie do wdrożenia mapM. Numer m będzie taki sam, jak w przypadku pierwszego połączenia z numerem Data.Vector.Unboxed.mapM. Ale ponieważ grzbiet tego strumienia znajduje się wewnątrz funktora m, nie można z nim pracować, jeśli masz aplikator tylko dla m.

Zobacz także ten numer na vector GitHub repo: Weaken constraint on mapM.

Nota prawna: Nie wiem, jak działa fuzja. Nie wiem, jak działa vector.