Maxime Henrion wrote: > Hello all, > > > I have found myself writing instances of Show for some types of > mine, and I did so by defining the showsPrec function, for performance > reasons. I ended up with code that I find quite inelegant. Here's > an example: > > data Move = Move { > movePiece :: PieceType, > moveFile :: Maybe File, > moveTarget :: Square, > moveIsCapture :: Bool > --movePromotion :: Maybe PieceType > } > deriving (Eq) > > instance Show Move where > showsPrec _ > Move { > movePiece = p, > moveFile = f, > moveTarget = s, > moveIsCapture = c > } = (if p /= Pawn then shows p else id) . > (maybe id shows f) . > (if c then ('x':) else id) . > shows s > > I considered writing a conditional composiion combinator to avoid all > the 'if foo then f else id' code. Something looking like this: > > f .? True g = f . g > f .? False g = f > > I'm not sure this is the best approach though, and I would be happy > to hear about your suggestions for improving the style of this code, > or any other comment that you think is appropriate. > > Thanks, > Maxime
Well, since ((.) :: ShowS -> ShowS -> ShowS) is a Monoid, you can use Writer to create the result: > import Control.Monad > import Control.Monad.Writer > > type Writes = Writer ShowS () > > data PieceType = Pawn | Other deriving (Eq,Show) > type File = Int > type Square = Int > > data Move = Move { > movePiece :: PieceType, > moveFile :: Maybe File, > moveTarget :: Square, > moveIsCapture :: Bool > --movePromotion :: Maybe PieceType > } > deriving (Eq) > > instance Show Move where showsPrec = showsPrec_Move > > showsPrec_Move :: Int -> Move -> ShowS > showsPrec_Move _ Move { movePiece = p > , moveFile = f > , moveTarget = s > , moveIsCapture = c } = execWriter $ do > when (p/=Pawn) (tell (shows p)) > maybe (return ()) (tell . shows) f > when c (tell ('x':)) > tell (shows s) > > testMove = Move Other (Just 6) 10 True > which gives > *Main> testMove > Other6x10 > *Main> testMove { movePiece=Pawn } > 6x10 > *Main> testMove { movePiece=Pawn, moveIsCapture=False } > 610 _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe