Mainate/src/Stream.hs

51 lines
1.6 KiB
Haskell

module Stream (
Stream(..)
) where
import Data.List (intercalate)
data Stream a = Stream [(a, Stream a)] deriving Show
instance Monoid (Stream a) where
mempty = fromList []
mappend (Stream []) b = b
mappend (Stream pairs) b = Stream $ (\(a, stream) -> (a, stream `mappend` b)) <$> pairs
fromList :: [a] -> Stream a
fromList [] = Stream []
fromList (pair:pairs) = Stream [(pair, fromList pairs)]
infinite :: a -> Stream a
infinite a = Stream [(a, infinite a)]
merge :: Eq a => Stream a -> Stream a -> Stream a
merge (Stream aPairs) (Stream bPairs) = Stream $ foldl mergeOrAdd aPairs bPairs
where
openAt _ l [] = (l, [])
openAt p up l@(x:xs) = if p x then (up, l) else openAt p (x:up) xs
zipUp ([], l) = l
zipUp (x:xs, l) = zipUp (xs, x:l)
mergeOrAdd accumulator (b, bStream) = zipUp $
case openAt ((== b) . fst) [] accumulator of
(up, []) -> (up, [(b, bStream)])
(up, (x, xStream):down) -> (up, (x, merge xStream bStream):down)
showTree :: Show a => Stream a -> String
showTree = intercalate "\n" . getLines
where
getLines (Stream []) = [""]
getLines (Stream pairs) =
concat $ (\(a, stream) -> showElem a $ getLines stream) <$> pairs
showElem :: Show a => a -> [String] -> [String]
showElem _ [] = []
showElem a [l] = ["" ++ show a ++ "" ++ l]
showElem a (l:ls) =
let prefix = "" ++ show a ++ " ─┬" in
let padding = take (length prefix - 1) $ repeat ' ' in
(prefix ++ l) : (pad padding ls)
where
pad _ [] = []
pad padding [x] = [padding ++ '╰' : x]
pad padding (x:xs) = (padding ++ '├' : x) : (pad padding xs)