Mainate/src/Transducer.hs

35 lines
1.2 KiB
Haskell

{-# LANGUAGE NamedFieldPuns #-}
module Transducer (
Transducer
, fromList
, run
) where
import Stream (Stream(..), merge)
import qualified Stream (empty)
import Graph (Graph(..), Vertex(..), Zipper(..), editLabel, follow, open, rewind, singleton, weave)
type Transducer input output = Graph input [output]
empty :: Transducer input output
empty = open $ singleton []
add :: Ord input => Transducer input output -> ([input], output) -> Transducer input output
add transducer (path, output) =
rewind $ editLabel (weave transducer path) (output:)
fromList :: Ord input => [([input], output)] -> Transducer input output
fromList = foldl add empty
run :: (Ord input, Eq output) => Transducer input output -> Stream input -> Stream output
run transducer (Stream inputs) = foldl (\(Stream outputs) (input, stream) ->
case follow transducer input of
Nothing -> case context transducer of
Top -> run (rewind transducer) stream
_ -> Stream.empty
Just newState@(Graph {focus}) ->
Stream ((emit stream <$> label focus) ++ outputs) `merge` run newState stream
) Stream.empty inputs
where
emit stream output = (output, run (rewind transducer) stream)