packages feed

quickspec-2.1: examples/PrettyPrintingModel.hs

-- Pretty-printing combinators, testing against a model implementation.
-- Illustrates running QuickSpec on a progressively larger set of signatures.
-- See the QuickSpec paper for more details.
{-# LANGUAGE DeriveDataTypeable, TypeOperators #-}
import Prelude hiding ((<>))
import Control.Monad
import Test.QuickCheck
import QuickSpec
import Data.Proxy

newtype Layout = Layout [(Int, String)]
  deriving (Typeable, Eq, Ord, Show)

instance Arbitrary Layout where
  arbitrary = fmap Layout (liftM2 (:) arbitrary arbitrary)

text :: String -> Layout
text s = Layout [(0, s)]

nest :: Int -> Layout -> Layout
nest k (Layout l) = Layout [(i+k, s) | (i, s) <- l]

($$) :: Layout -> Layout -> Layout
Layout xs $$ Layout ys = Layout (xs ++ ys)

(<>) :: Layout -> Layout -> Layout
Layout xs <> Layout ys =
  combine (init xs) (last xs) (head ys) (tail ys)
  where
    combine xs (i, s) (j, t) ys =
      Layout xs $$
      Layout [(i, s ++ t)] $$
      nest (i + length s - j) (Layout ys)

nesting :: Layout -> Int
nesting (Layout ((i,_):_)) = i

main = quickSpec [
  withMaxTermSize 9,
  monoType (Proxy :: Proxy Layout),
  background [
    con "\"\"" "",
    con "++" ((++) :: String -> String -> String),
    con "0" (0 :: Int),
    con "+" ((+) :: Int -> Int -> Int),
    con "length" (length :: String -> Int) ],
  series [sig1, sig2]]
  where
    sig1 = [
      con "text" text,
      con "nest" nest,
      con "$$" ($$),
      con "<>" (<>) ]
    sig2 = [con "nesting" nesting]