Found a nicer formulation that doesn't require transitivity or index agglomeration and swapped argument of w for more reusability with at / atAll

This commit is contained in:
Tissevert 2020-02-26 17:14:43 +01:00
parent bdbc5f7351
commit f4df4aab22
3 changed files with 29 additions and 43 deletions

View file

@ -2,9 +2,9 @@
{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE MultiParamTypeClasses #-}
module PDF ( module PDF (
AllLayers(..) Document(..)
, Document(..) , EOLStyle(..)
, EOLStyleK(..) , Layers(..)
, UnifiedLayers(..) , UnifiedLayers(..)
, parseDocument , parseDocument
, render , render
@ -42,21 +42,21 @@ instance Output Document where
Output.line (printf "%%PDF-%s" pdfVersion) Output.line (printf "%%PDF-%s" pdfVersion)
`mappend` output layers `mappend` output layers
data EOLStyleK = EOLStyleK data EOLStyle = EOLStyle
data AllLayers = AllLayers data Layers = Layers
data UnifiedLayers = UnifiedLayers data UnifiedLayers = UnifiedLayers
instance Monad m => Box m EOLStyleK Document EOL.Style where instance Monad m => Box m EOLStyle Document EOL.Style where
r EOLStyleK = return . eolStyle r EOLStyle = return . eolStyle
w EOLStyleK document eolStyle = return $ document {eolStyle} w EOLStyle eolStyle document = return $ document {eolStyle}
instance Monad m => Box m UnifiedLayers Document Layer where instance Monad m => Box m UnifiedLayers Document Layer where
r UnifiedLayers = return . unify . layers r UnifiedLayers = return . unify . layers
w UnifiedLayers document layer = w AllLayers document [layer] w UnifiedLayers layer = w Layers [layer]
instance Monad m => Box m AllLayers Document [Layer] where instance Monad m => Box m Layers Document [Layer] where
r AllLayers = return . layers r Layers = return . layers
w AllLayers document layers = return $ document {layers = layers} w Layers layers document = return $ document {layers = layers}
render :: Document -> Lazy.ByteString render :: Document -> Lazy.ByteString
render document@(Document {eolStyle}) = Output.render eolStyle document render document@(Document {eolStyle}) = Output.render eolStyle document

View file

@ -6,11 +6,9 @@
module PDF.Box ( module PDF.Box (
Box(..) Box(..)
, I(..) , I(..)
, (.@)
, at , at
, atAll
, edit , edit
, forAll
, modifyAt
) where ) where
import Control.Monad.Fail (MonadFail(..)) import Control.Monad.Fail (MonadFail(..))
@ -19,28 +17,20 @@ import Data.Map (Map)
import qualified Data.Map as Map (insert, lookup, member) import qualified Data.Map as Map (insert, lookup, member)
import Prelude hiding (fail) import Prelude hiding (fail)
data I = I Int newtype I = I Int
class Monad m => Box m i a b | m a i -> b where class Monad m => Box m i a b | m a i -> b where
r :: i -> a -> m b r :: i -> a -> m b
w :: i -> a -> b -> m a w :: i -> b -> a -> m a
edit :: Box m i a b => i -> (b -> m b) -> a -> m a at :: Box m i a b => i -> (b -> m b) -> a -> m a
edit i f a = at i f a = r i a >>= f >>= flip (w i) a
r i a >>= f >>= w i a
at :: (MonadState a m, Box m i a b) => i -> (b -> m c) -> m c atAll :: (Traversable t, Monad m, Box m i a (t b)) => i -> (b -> m b) -> a -> m a
at i f = get >>= r i >>= f atAll i f = at i $ (mapM f)
modifyAt :: (MonadState a m, Box m i a b) => i -> (b -> m b) -> m () edit :: MonadState a m => (a -> m a) -> m ()
modifyAt i f = get >>= edit i f >>= put edit f = get >>= f >>= put
forAll :: (MonadState a m, Box m i a (t b)) => i -> (b -> m ()) -> m ()
forAll = undefined
instance (Box m i a b, Box m j b c) => Box m (i, j) a c where
r (i, j) a = r i a >>= r j
w (i, j) a c = edit i (flip (w j) c) a
instance MonadFail m => Box m I [a] a where instance MonadFail m => Box m I [a] a where
r (I i) = getAt i r (I i) = getAt i
@ -48,7 +38,7 @@ instance MonadFail m => Box m I [a] a where
getAt _ [] = fail $ "Index out of bounds " ++ show i getAt _ [] = fail $ "Index out of bounds " ++ show i
getAt 0 (x:_) = return x getAt 0 (x:_) = return x
getAt k (_:xs) = getAt (k+1) xs getAt k (_:xs) = getAt (k+1) xs
w (I i) l newX = setAt i l w (I i) newX = setAt i
where where
setAt _ [] = fail $ "Index out of bounds " ++ show i setAt _ [] = fail $ "Index out of bounds " ++ show i
setAt 0 (_:xs) = return (newX:xs) setAt 0 (_:xs) = return (newX:xs)
@ -56,11 +46,7 @@ instance MonadFail m => Box m I [a] a where
instance (Ord k, MonadFail m) => Box m k (Map k a) a where instance (Ord k, MonadFail m) => Box m k (Map k a) a where
r k = maybe (fail "Unknown key") return . Map.lookup k r k = maybe (fail "Unknown key") return . Map.lookup k
w k aMap a w k a aMap
| Map.member k aMap = | Map.member k aMap =
return $ Map.insert k a aMap return $ Map.insert k a aMap
| otherwise = fail "Unknown key" | otherwise = fail "Unknown key"
infixr 6 .@
(.@) :: a -> b -> (a, b)
(.@) = (,)

View file

@ -2,8 +2,8 @@
{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE MultiParamTypeClasses #-}
module PDF.Layer ( module PDF.Layer (
AllObjects(..) Layer(..)
, Layer(..) , Objects(..)
, unify , unify
) where ) where
@ -50,11 +50,11 @@ instance Output Layer where
where where
Structure {xRef, trailer} = docStructure Structure {xRef, trailer} = docStructure
data AllObjects = AllObjects data Objects = Objects
instance Monad m => Box m AllObjects Layer (Map ObjectId Object) where instance Monad m => Box m Objects Layer (Map ObjectId Object) where
r AllObjects = return . objects r Objects = return . objects
w AllObjects layer@(Layer {occurrences, docStructure}) newObjects = w Objects newObjects layer@(Layer {occurrences, docStructure}) =
return $ layer { return $ layer {
occurrences = keptOccurrences ++ newOccurrences occurrences = keptOccurrences ++ newOccurrences
, objects = newObjects , objects = newObjects