Давным-давно я написал
статью по разборщики на потоковых процессорах.
Так вот, работают они совершенно нелинейно. Простой разборщик наподобие \n -> prun (pmany (ptoken '1' `ppar` ptoken '2')) (replicate n '1') работает за квадратичное от n время.
Есть у меня подозрение, что это из-за того, что ppar реализован не как исключающий ppar монадных
(
Read more... )
data SP a b = NullSP | Put b (SP a b) | Get (a -> SP a b)
failSP = NullSP
returnSP a = Put a NullSP
seqSP NullSP f = NullSP
seqSP (Get h) f = Get $ \a -> seqSP (h a) f
seqSP (Put b spa) f = f b `parSP` seqSP spa f
parSP :: SP a b -> SP a b -> SP a b
parSP NullSP spb = spb
parSP spa NullSP = spa
parSP (Put b spa) spb = Put b $ parSP spa spb
parSP spa (Put b spb) = Put b $ parSP spa spb
parSP (Get fa) (Get fb) = Get $ \a -> parSP (fa a) (fb a)
mapSP f NullSP = NullSP
mapSP f (Get g) = Get $ \a -> mapSP f (g a)
mapSP f (Put b sp) = Put (f b) (mapSP f sp)
instance Monad (SP a) where
return = returnSP
(>>=) = seqSP
fail _ = failSP
instance Functor (SP a) where
fmap = mapSP
readInput = Get $ returnSP
char c = do
a <- readInput ( ... )
Reply
Нисколечки она не отбрасывается.
Рассинхронизации не произойдет, поскольку мы сперва выдадим все возможные на данный момент результаты, а затем запросим вход.
Вообще, потоковые процессоры мне нравятся. Только я их дальше разборщиков не освоил. ;)
Reply
Reply
Reply
Reply
Reply
Где-то так:
altSP NullSP spb = spb
altSP spa NullSP = spa
altSP spa@(Put _ _) _ = spa
altSP (Get fa) (Get fb) = Get $ \a -> parSP (fa a) (fb a)
altSP (Get fa) spb = Get $ \a -> fa a `altSP` bufInput a spb
bufInput a NullSP = NullSP
bufInput a (Get f) = f a
bufInput a (Put b spb) = Put b $ bufInput a spb
Все хорошо, но есть один маленький недостаток - не работает. :)
пробовал на:
option s p = p `altSP` return s
test = parseSP (option '_' (char '1') >> char '2') "2 "
выдает почему-то пустой список
Reply
Я сделал вот так:
altSP NullSP spb = spb
altSP spa NullSP = spa
altSP spa@(Put _ _) _ = spa
altSP (Get fa) (Get fb) = Get $ \a -> parSP (fa a) (fb a)
altSP a@(Get fa) (Put o b) = Put o $ altSP a bи оно заработало. ;)
Reply
Кстати, там у меня опечатка (которая осталась и в твоем коде: вместо altSP написанно parSP)
Reply
Reply
Leave a comment