[<<][meta_siso][>>][..]
Fri Aug 14 16:53:57 EDT 2015

Allowing expressions

-- Allow use of nested expression syntax when sharing is not an issue.
-- expr2 :: Monad m => (a -> b -> m c) -> m a -> m b -> m c
-- expr2 f a b = join $ liftM2 f a b

-- Allow expression syntax.
class MExpr f1 f2 where
  mexpr :: f1 -> f2
  
instance MRepr m r => MExpr (r a     -> r a     -> m (r b))
                            (m (r a) -> m (r a) -> m (r b)) where
  mexpr f x y = join $ liftM2 f x y
  
instance MRepr m r => MExpr (r a -> r a     -> m (r b))
                            (r a -> m (r a) -> m (r b)) where
  mexpr f x y = do; y' <- y; f x y';
                  
instance MRepr m r => MExpr (r a     -> r a -> m (r b))
                            (m (r a) -> r a -> m (r b)) where
  mexpr f x y = do; x' <- x; f x' y;



This doesn't work so well.



I want to express this:

  If the argument is (m (r (m (r t)))) then join it, else leave it
  flat.
  


class Monad m => MaybeJoin m r t t' where maybeJoin :: m t' -> m (r t)
  
instance Monad m => MaybeJoin m r t    (r t)  where maybeJoin = id  
instance Monad m => MaybeJoin m r t (m (r t)) where maybeJoin = join



But this whole thing seems to be ill-conceived because of the way type
inference works.

The bottom case needs to be tagged somehow.


Tried this, but I'm loosing energy.. Still ambiguous types.


data V t = V t
class Monad m => VJoin m t' t  where vJoin :: m t' -> m (V t)
instance Monad m      => VJoin m (V t)  t where vJoin = id
instance VJoin m t' t => VJoin m (m t') t where vJoin = vJoin . join

v2 f a b = do
  V a' <- vJoin $ return a
  V b' <- vJoin $ return b
  r <- f a' b'
  return $ V r



*Lib> :t v2 add (V zero) (V zero)
v2 add (V zero) (V zero)
  :: (Ring m2 r2 t2, Ring m1 r1 t1, Ring m r t,
      VJoin m (V (r1 t1)) (r t), VJoin m (V (r2 t2)) (r t)) =>
     m (V (r t))








data V t = V t
class Monad m => VJoin m t' t | t' -> t where vJoin :: m t' -> m (V t)
instance Data m r         => VJoin m (V (r t)) (r t) where vJoin = id
instance VJoin m t' (r t) => VJoin m (m t')    (r t) where vJoin = vJoin . join

v2 :: (Ring m r t, VJoin m t1 (r t), VJoin m t2 (r t)) => 
      (r t -> r t -> m (r t)) -> t1 -> t2 -> m (V (r t))
v2 f a b = do
  V a' <- vJoin $ return a
  V b' <- vJoin $ return b
  r <- f a' b'
  return $ V r




[Reply][About]
[<<][meta_siso][>>][..]