Problem with forall type in type declaration

Hi, Assuming this: run :: Monad IO a -> IO a data Test = Test { f } Here I'd like to set f to run, like "Test run". Then what is the type of f? The confusing (me) part is that, the argument pass to f is not fixed on return type, like "f1 :: Monad IO ()", "f2 :: Monad IO Int". So "data Test a = Test { f :: Monad IO a -> IO a} does not work. -- 竹密岂妨流水过 山高哪阻野云飞 And for G+, please use magiclouds#gmail.com.

run :: Monad IO a -> IO a
Actually this type is wrong. Monad has to appear as a class constraint, for
instance :
run :: Monad m => m a -> IO a
Are you trying to make:
run :: IO a -> IO a
??
2012/5/4 Magicloud Magiclouds
Hi, Assuming this: run :: Monad IO a -> IO a data Test = Test { f }
Here I'd like to set f to run, like "Test run". Then what is the type of f? The confusing (me) part is that, the argument pass to f is not fixed on return type, like "f1 :: Monad IO ()", "f2 :: Monad IO Int". So "data Test a = Test { f :: Monad IO a -> IO a} does not work. -- 竹密岂妨流水过 山高哪阻野云飞
And for G+, please use magiclouds#gmail.com.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Sorry, it was just a persudo code. This might be more clear:
run :: (Monad m) => m IO a -> IO a
On Fri, May 4, 2012 at 4:32 PM, Yves Parès
run :: Monad IO a -> IO a
Actually this type is wrong. Monad has to appear as a class constraint, for instance :
run :: Monad m => m a -> IO a
Are you trying to make:
run :: IO a -> IO a ??
2012/5/4 Magicloud Magiclouds
Hi, Assuming this: run :: Monad IO a -> IO a data Test = Test { f }
Here I'd like to set f to run, like "Test run". Then what is the type of f? The confusing (me) part is that, the argument pass to f is not fixed on return type, like "f1 :: Monad IO ()", "f2 :: Monad IO Int". So "data Test a = Test { f :: Monad IO a -> IO a} does not work. -- 竹密岂妨流水过 山高哪阻野云飞
And for G+, please use magiclouds#gmail.com.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- 竹密岂妨流水过 山高哪阻野云飞 And for G+, please use magiclouds#gmail.com.

If one parameter is not enough, you always can add more: Test m a b = Test { f :: m IO a -> IO b } This way, if run :: m IO a -> IO a then Test run :: Test m a a But for other type for your run function run' :: m IO a -> IO b you get Test run' :: Test m a b So you can have different types in input and output. Anyway, your type 'm' is applied to other two types (m IO a), so it cannot be a monad, because monads have arity 1 as type constructors, i.e. monads have kind (* -> *). Is perhaps 'm' some kind of monad transformer? Well, that's all I can say from your explanation of the problem! Hope it helps! Daniel Díaz.

Sorry to use Monad as the example, I meant this one:
run :: MonadTrans m => m IO a -> IO a
And Daniel, I do not think adding another type "b" a good idea. Since
"run" could actually return any inside type (depending on another
function that passed to it). Even simple as different tuples would
destroy this solution.
On Fri, May 4, 2012 at 10:05 PM, Daniel Díaz Casanueva
If one parameter is not enough, you always can add more:
Test m a b = Test { f :: m IO a -> IO b }
This way, if
run :: m IO a -> IO a
then
Test run :: Test m a a
But for other type for your run function
run' :: m IO a -> IO b
you get
Test run' :: Test m a b
So you can have different types in input and output. Anyway, your type 'm' is applied to other two types (m IO a), so it cannot be a monad, because monads have arity 1 as type constructors, i.e. monads have kind (* -> *). Is perhaps 'm' some kind of monad transformer?
Well, that's all I can say from your explanation of the problem! Hope it helps!
Daniel Díaz.
-- 竹密岂妨流水过 山高哪阻野云飞 And for G+, please use magiclouds#gmail.com.

Anyone could help on this?
On Fri, May 4, 2012 at 11:12 PM, Magicloud Magiclouds
Sorry to use Monad as the example, I meant this one: run :: MonadTrans m => m IO a -> IO a
And Daniel, I do not think adding another type "b" a good idea. Since "run" could actually return any inside type (depending on another function that passed to it). Even simple as different tuples would destroy this solution.
On Fri, May 4, 2012 at 10:05 PM, Daniel Díaz Casanueva
wrote: If one parameter is not enough, you always can add more:
Test m a b = Test { f :: m IO a -> IO b }
This way, if
run :: m IO a -> IO a
then
Test run :: Test m a a
But for other type for your run function
run' :: m IO a -> IO b
you get
Test run' :: Test m a b
So you can have different types in input and output. Anyway, your type 'm' is applied to other two types (m IO a), so it cannot be a monad, because monads have arity 1 as type constructors, i.e. monads have kind (* -> *). Is perhaps 'm' some kind of monad transformer?
Well, that's all I can say from your explanation of the problem! Hope it helps!
Daniel Díaz.
-- 竹密岂妨流水过 山高哪阻野云飞
And for G+, please use magiclouds#gmail.com.
-- 竹密岂妨流水过 山高哪阻野云飞 And for G+, please use magiclouds#gmail.com.

On 04/05/12 09:08, Magicloud Magiclouds wrote:
Hi, Assuming this: run :: Monad IO a -> IO a data Test = Test { f }
Here I'd like to set f to run, like "Test run". Then what is the type of f? The confusing (me) part is that, the argument pass to f is not fixed on return type, like "f1 :: Monad IO ()", "f2 :: Monad IO Int". So "data Test a = Test { f :: Monad IO a -> IO a} does not work.
You need to explicitly add "forall a." to the type of f. For example: {-# LANGUAGE PolymorphicComponents #-} run :: MonadIO m => m a -> IO a newtype Test = Test { f :: forall m a. MonadIO m a => m a -> IO a } Twan
participants (4)
-
Daniel Díaz Casanueva
-
Magicloud Magiclouds
-
Twan van Laarhoven
-
Yves Parès