In article <200501071653.j07GrHMu002630@asterix.cs.indiana.edu>, Amr A Sabry <sabry@cs.indiana.edu> wrote:
The type Vec below is almost a monad: - the operations vreturn and @>>= are almost of the right type (they have an additional constraint FinSet a =>) - the operations vreturn and @>>= satisfy the monad laws
class Eq a => FinSet a where enumerate :: [a]
newtype Vec a = Vec (a -> Float) unV (Vec f) = f
vreturn :: FinSet a => a -> Vec a vreturn a = Vec (\ b -> if a==b then 1 else 0)
(@>>=) :: FinSet a => Vec a -> (a -> Vec b) -> Vec b (Vec va) @>>= f = Vec (\ b -> sum [ (va a) * (unV (f a) b) | a <- enumerate])
Because of the additional type constraint (FinSet a =>) we cannot make the type Vec an instance of the class Monad, and hence we cannot use the do-notation to express our computations.
You can to do this with GADTs: data MyVec a where MkMyVec :: (FinSet a) => Vec a -> MyVec a instance Monad MyVec where return a = MkMyVec (vreturn a) etc. GADTs are scheduled for version 6.4 of GHC. The version of GHC now in CVS does not currently allow this however, see GHC bug #1097046. -- Ashley Yakeley, Seattle WA