There's warstwa abstrakcji wykorzystywane przez parsec, typ klasy Stream
, wygląda to tak:Dlaczego wyrazy Parsec są wyraźnie zaznaczone jako Tekst, ale nie ByteString?
class (Monad m, ShowToken t) => Stream s m t | s -> t where
uncons :: s -> m (Maybe (t, s))
instance (Monad m, ShowToken t) => Stream [t] m t where
uncons [] = return Nothing
uncons (t:ts) = return $ Just (t, ts)
{-# INLINE uncons #-}
instance Monad m => Stream CL.ByteString m Char where
uncons = return . CL.uncons
instance Monad m => Stream C.ByteString m Char where
uncons = return . C.uncons
instance Monad m => Stream T.Text m Char where
uncons = return . T.uncons
{-# INLINE uncons #-}
instance Monad m => Stream TL.Text m Char where
uncons = return . TL.uncons
{-# INLINE uncons #-}
Zastanawiam się, czy inline jest dobrym pomysłem tutaj, to dlaczego uncons
w ByteString
jest instancją Stream
nie inlined?
Czy wszystkie te funkcje powinny być w jednej linii, czy też nie powinny być tak różne, czy Text
i ByteString
są tak różne, że powinniśmy wstawiać jeden i nie wpisywać drugiego?
Jeśli mogę zrobić dźgnięcie, listy i "Tekst" podlegają fuzji, ale 'ByteString'-s nie są. –
@ AndrásKovács, więc czy to oznacza, że wydajność Parsec dla 'ByteString' jest * bardzo * słaba i podkreślanie tych funkcji nic nie zmieni? – Mark
Fuzja polega przede wszystkim na wstawianiu, a jej brak może czasem pogorszyć wydajność, stąd pragmy (jak sądzę). Bez pragmas GHC nadal będzie często inline metody. Również wydajność dla ByteString nie jest "bardzo słaba", myślę, że jest najszybsza dla Parsetu. –