Anyway, if the idea is to ultimately wrap every value in an expression like ([1,2]+[3,4]) in a 'run' application, that doesn't sound very useful. Program structure might be improved, but it would be bloated out by these calls. Also, I don't know what would happen to the readability of type checker errors. I think it would be more useful if the compiler took care of this automatically. I think it would be worthwhile just for making imperative code more readable. Frederik P.S. By the way, did you misunderstand what I meant by 'automatic lifting'? Note that I'm talking about "lift" as in 'liftM', not 'lift' from MonadTrans. On Fri, Sep 09, 2005 at 01:17:57PM -0700, Frederik Eaton wrote:
On Thu, Sep 08, 2005 at 09:34:33AM +0100, Keean Schupke wrote:
Can't you do automatic lifting with a "Runnable" class:
class Runnable x y where run :: x -> y
instance Runnable (m a) (m a) where run = id
instance Runnable (s -> m a) (s -> m a) where run = id instance (Monad m,Monad n,MonadT t m,Runnable (m a) (n a)) => Runnable (t m a) (n a) where run = run . down
Interesting...
instance (Monad m,MonadT t m,Monad (t m)) => Runnable (t m a) (m a) where run = down
The above is redundant, right?
Where:
class (Monad m,Monad (t m)) => MonadT t m where up :: m a -> t m a down :: t m a -> m a
For example for StateT: ...
So, 'run' is more like a form of casting than running, right?
How do I use it to add two lists? Where do the 'run' applications go? Do you have an explicit example?
I was trying to test things out, and I'm running into problems with the type system, for instance when I declare:
class Cast x y where cast :: x -> y
instance Monad m => Cast x (m x) where cast = return
p1 :: (Monad m, Num a) => m (a -> a -> a) p1 = cast (+)
it says:
Could not deduce (Cast (a1 -> a1 -> a1) (m (a -> a -> a))) from the context (Monad m, Num a) arising from use of `cast' at runnable1.hs:14:5-8
But this should match the instance I declared, I don't understand what the problem is.
Frederik