ADPfusion-0.2.0.0: ADP/Fusion/Examples/Palindrome.hs
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE RecordWildCards #-}
module ADP.Fusion.Examples.Palindrome where
import Data.Vector.Fusion.Stream.Monadic (Stream (..))
import qualified Data.Vector.Fusion.Stream.Monadic as S
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector as V
import Data.Array.Repa.Index
import Control.Monad
import Control.Monad.Trans.Class
import qualified Control.Monad.Trans.Writer.Lazy as W
import qualified Control.Arrow as A
import Data.PrimitiveArray as PA
import Data.PrimitiveArray.Zero as PA
import ADP.Fusion hiding (empty)
import ADP.Fusion.Empty hiding (empty)
import ADP.Fusion.Chr
import ADP.Fusion.Table
import Data.Array.Repa.Index.Subword
import ADP.Fusion.TH
data SignatureT m x r = Signature
{ pair :: Char -> x -> Char -> x
, empty :: () -> x
, h :: Stream m x -> m r
}
-- makeAlgebraProduct ''SignatureT
{-
-- gPalindrome :: Signature m x -> Empty -> Char -> tbl -> (tbl, Subword -> m x)
gPalindrome Signature{..} e c s =
( s, ( empty <<< e |||
pair <<< c % s % c ... h
)
)
{-# INLINE gPalindrome #-}
aPair :: Monad m => Signature m Int Int
aPair = Signature
{ pair = \l x r -> if l==r then (x+4983) else -999999
, empty = \() -> 4711
, h = S.foldl' max (-888888)
}
{-# INLINE aPair #-}
aPretty :: Monad m => Signature m String (Stream m String)
aPretty = Signature
{ pair = \l x r -> "(" ++ x ++ ")"
, empty = \() -> ""
, h = return . id
}
(<**) :: (Monad m, CombElem x' x) => Signature m x x' -> Signature m y y' -> Signature m (x,Stream m y) y'
(<**) x y = Signature
{ pair = \l (zx,zy) r -> (pair x l zx r, S.map (\z -> pair y l z r) zy)
, empty = \() -> (empty x (), S.singleton $ empty y ())
, h = \zs -> do hfst <- h x $ S.map fst zs
h y $ S.concatMap snd . S.filter (combElem hfst . fst) $ zs
}
{-# INLINE (<**) #-}
(***) :: (Monad m) => Signature m x x' -> Signature m y y' -> Signature m (x,y) (x',y')
(***) x y = Signature
{ pair = \l (zx,zy) r -> (pair x l zx r, pair y l zy r)
, empty = \() -> (empty x (), empty y ())
-- , h = \zs -> do hfst <- h x $ S.map fst zs
-- let phfs = S.concatMap snd . S.filter (combElem hfst . fst) $ zs
-- hsnd <- h y phfs
}
{-# INLINE (***) #-}
class CombElem x y where
combElem :: x -> y -> Bool
instance (Eq x) => CombElem x x where
combElem = (==)
instance (VU.Unbox x, Eq x) => CombElem (VU.Vector x) x where
combElem xs y = VU.elem y xs
instance (Eq x) => CombElem (V.Vector x) x where
combElem xs y = V.elem y xs
palindromeFill :: VU.Vector Char -> IO (PA.Unboxed (Z:.Subword) Int)
palindromeFill inp = do
let n = VU.length inp
!t' <- newWithM (Z:.subword 0 0) (Z:.subword 0 n) 0
let t= mTblSw EmptyT t'
let b = chr inp
let e = Empty
fillTable $ gPalindrome aPair e b t
freeze t'
{-# NOINLINE palindromeFill #-}
fillTable (MTbl _ tbl, f) = do
let (_,Z:.Subword (0:.n)) = boundsM tbl
forM_ [n,n-1..0] $ \i -> forM_ [i..n] $ \j -> do
(f $ subword i j) >>= writeM tbl (Z:.subword i j)
{-# INLINE fillTable #-}
-}