Template for typeclass validation in Haskell

Haskell is the toughest thing I've set out to learn so far. Haskell from First Principles has done a great job of building up my understanding a piece at a time. The author breaks down the complexity and instills comprehension without hand waving metaphors, so you earn a good intuitive grasp backed up by a solid understanding of the actual logic. By the time he says "a monad is an applicative functor ..." you are fully prepared to know exactly what that means in terms of the functions available and the programmatic laws they follow.

It's good stuff. I'm about 2/3 of the way through.

There's a bit where you have to implement law-abiding instances of the major typeclasses that build up the infamous monad. I'm recording a template of the way those tests are constructed. When it gets time to write real code, tests will need to be broken out of the main library, but that's the easy part. I'll want this for my notes.

module TypeCheckingExample where

-- Imports for testing only
import Test.QuickCheck
import Test.QuickCheck.Checkers
import Test.QuickCheck.Classes


-- Data Constructor

data Demo a = Demo a deriving (Eq, Show)

-- TypeClass instances

instance (Monoid a) => Monoid (Demo a) where
    mempty = undefined
    mappend = undefined

instance Functor Demo where
    fmap = undefined

instance Applicative Demo where
    pure = undefined
    (<*>) = undefined

instance Monad Demo where
    return = undefined
    (>>=) = undefined

-- Testing Section

-- Testing for associativity requires a three-tuple of types for which
-- 'arbitratry' can produce functions
type Associatable = (Integer, Char, String)


-- Typeclass instances required for QuickCheck

instance (Arbitrary a) => Arbitrary (Demo a) where
    arbitrary = undefined

instance Eq a => EqProp (Demo a) where
    (=-=) = eq


-- main

main :: IO ()
main = do
    quickBatch $ monoid (undefined :: Demo [Integer])
    quickBatch $ functor (undefined :: Demo Associatable)
    quickBatch $ applicative (undefined :: Demo Associatable)
    quickBatch $ monad (undefined :: Demo Associatable)