I've been unable to get the following (simplified) code to be accepted by GHCi (8.0.1 and 8.0.2)
Prelude> let (x, y) = (1, return 2) <interactive>:1:5: error: • Could not deduce (Monad m0) from the context: Num t bound by the inferred type for ‘x’: Num t => t at <interactive>:1:5-24 The type variable ‘m0’ is ambiguous • When checking that the inferred type x :: forall a (m :: * -> *) t. (Num a, Num t, Monad m) => t is as general as its inferred signature x :: forall t. Num t => t and I don't seem to be able to provide a type signatures that GHCi is okay with Prelude> let { x :: Int; y :: Monad m => m Int; (x, y) = (1, return 2) } <interactive>:5:40: error: • Ambiguous type variable ‘m0’ prevents the constraint ‘(Monad m0)’ from being solved. • When checking that the inferred type x :: forall a (m :: * -> *) t (m1 :: * -> *). (Num a, Num t, Monad m) => t is as general as its signature x :: Int Prelude> let (x, y) = (1, return 2) :: (Int, Monad m => m Int) <interactive>:4:31: error: • Illegal qualified type: Monad m => m Int GHC doesn't yet support impredicative polymorphism • In an expression type signature: (Int, Monad m => m Int) In the expression: (1, return 2) :: (Int, Monad m => m Int) In a pattern binding: (x, y) = (1, return 2) :: (Int, Monad m => m Int) Prelude> let (x,y) = (1,return 2) :: Monad m => (Int, m Int) <interactive>:7:5: error: • Ambiguous type variable ‘m0’ prevents the constraint ‘(Monad m0)’ from being solved. • When checking that the inferred type x :: forall (m :: * -> *). Monad m => Int is as general as its inferred signature x :: Int It seems the constraint on y leaks to x where it isn't well formed? Any help and/or explanations would be greatly appreciated. In my actual code the assignment is from the return value of a function so I can't just split it into two separate statements. Thanks! -Tyson _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post. |
I am not sure really what you are trying to do, but here are a few
approaches which I think may solve your problem. 1. Calculate the monadic value outside or fmap over the tuple constructor for instance do x <- functionCall return (y, x) or (y, ) <$> functionCall (uses the TupleSections extension) 2. Use explicit forall and scoped type variables If you really want to return a tuple with that monadic value from a function then the `Monad m` constraint must be on the function itself. Like so Compiled with ExplicitForAll and ScopedTypeVariables myFunction :: forall m. Monad m => m ... myFunction = let x :: m SomeType (y, x) = (..., return ...) in ... Which binds `m` to be of the same type as the outer `m`. This is necessary as there must be some way that even from outside the function we can figure out what concretely `m` actually is. Ergo it must be bound in some way to the functions type signature. 3. ExistentialTypes If you __really__ think you only need a `Monad` constraint on this type (which I doubt) you can use an existential to wrap things into generic monads. (Uses ExistentialTypes) data ExtMonad a = forall m. Monad m => ExtMonad m a The thing I don't quite understand is, if you have a function call, which produces the value, doesn't that call return a concrete monad? Rather than just `Monad m`? It sounds to me like you're actually barking up the wrong tree when you try and do what you are doing here so I suggest using something like approach 1 or 2 and perhaps rethinking if your problem may lay somewhere else. Regards Justus -- Justus Adam [hidden email] On Tue, Apr 18, 2017, at 12:41 PM, Tyson Whitehead wrote: > I've been unable to get the following (simplified) code to be accepted by > GHCi (8.0.1 and 8.0.2) > > Prelude> let (x, y) = (1, return 2) > <interactive>:1:5: error: > • Could not deduce (Monad m0) > from the context: Num t > bound by the inferred type for ‘x’: > Num t => t > at <interactive>:1:5-24 > The type variable ‘m0’ is ambiguous > • When checking that the inferred type > x :: forall a (m :: * -> *) t. (Num a, Num t, Monad m) => t > is as general as its inferred signature > x :: forall t. Num t => t > > and I don't seem to be able to provide a type signatures that GHCi is > okay with > > Prelude> let { x :: Int; y :: Monad m => m Int; (x, y) = (1, return 2) } > <interactive>:5:40: error: > • Ambiguous type variable ‘m0’ > prevents the constraint ‘(Monad m0)’ from being solved. > • When checking that the inferred type > x :: forall a (m :: * -> *) t (m1 :: * -> *). > (Num a, Num t, Monad m) => > t > is as general as its signature > x :: Int > > Prelude> let (x, y) = (1, return 2) :: (Int, Monad m => m Int) > <interactive>:4:31: error: > • Illegal qualified type: Monad m => m Int > GHC doesn't yet support impredicative polymorphism > • In an expression type signature: (Int, Monad m => m Int) > In the expression: (1, return 2) :: (Int, Monad m => m Int) > In a pattern binding: > (x, y) = (1, return 2) :: (Int, Monad m => m Int) > > Prelude> let (x,y) = (1,return 2) :: Monad m => (Int, m Int) > <interactive>:7:5: error: > • Ambiguous type variable ‘m0’ > prevents the constraint ‘(Monad m0)’ from being solved. > • When checking that the inferred type > x :: forall (m :: * -> *). Monad m => Int > is as general as its inferred signature > x :: Int > > It seems the constraint on y leaks to x where it isn't well formed? Any > help and/or explanations would be greatly appreciated. In my actual code > the assignment is from the return value of a function so I can't just > split it into two separate statements. > > Thanks! -Tyson > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post. |
In reply to this post by Tyson Whitehead
Hello Tyson, Thus quoth Tyson Whitehead at 19:41 on Tue, Apr 18 2017: > > I've been unable to get the following (simplified) code to be accepted > by GHCi (8.0.1 and 8.0.2) > > Prelude> let (x, y) = (1, return 2) [...] > and I don't seem to be able to provide a type signatures that GHCi is > okay with GHCi handles polymorphic types of interactive expressions somewhat differently from the polymorphic types of expressions loaded from files. (I'd be happy if someone could reproduce the explanation which I saw a couple times but which I cannot find any more.) Anyway, I put the following in tuple.hs: func :: Monad m => (Int, m Int) func = (1, return 2) Then, ghci tuple.hs swallows the file no problem and allows me to do *Main> func :: (Int, Maybe Int) (1, Just 2) (I have GHCi 8.0.2.) -- Sergiu _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post. signature.asc (497 bytes) Download Attachment |
In reply to this post by Tyson Whitehead
On Tue, Apr 18, 2017, 16:02 Joshua Grosso <[hidden email]> wrote:
Thanks for the input. You are correct that if I choose a
particular Monad instance GHCi accepts the code.
I believe it should be able to do the assignment without
choosing one though. It is, for example, okay with let y = return
2.
I'm thinking Sergiu is onto something about this having to do
with special GHCi handling.
Thanks! -Tyson
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post. |
In reply to this post by Sergiu Ivanov-2
Thanks Sergiu,
I know there was some defaulting, but didn't think much of it
beyond that. Special GHCi handling makes sense. Maybe I'll open a
ticket just in case this is an unintended effect.
Interesting observation about loading it from a file via typing it in. My code is actually a test case for use with the doctest package that I was just running manually to work out. I'm not sure if it does the equivalent of loading it from a file or not. Ultimately I wound up doing the binding via a case statement instead of let. It seems GHCi is okay with that. Cheers! -Tyon On Tue, Apr 18, 2017, 17:01 Sergiu Ivanov <[hidden email]>
wrote:
GHCi handles polymorphic types of interactive expressions somewhat _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post. |
Thus quoth Tyson Whitehead at 02:19 on Thu, Apr 20 2017: > > Interesting observation about loading it from a file via typing it in. Initially I suspected the culprit was the monomorphism restriction being turned off by default (:showi language in GHCi, (great thanks to Brandon Allbery who mentioned this command on another thread)), but I don't really see a difference when I turn it off. > My code is actually a test case for use with the doctest package that > I was just running manually to work out. I'm not sure if it does the > equivalent of loading it from a file or not. Oh, I see. > Ultimately I wound up doing the binding via a case statement instead > of let. It seems GHCi is okay with that. That's kind of funny. Seems somewhat inconsistent to my eye. -- Sergiu _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post. signature.asc (497 bytes) Download Attachment |
Free forum by Nabble | Edit this page |