Irritating Referential Transparency behavior?

Hello all, I came across something strange: This code compiles: ------------------------------------------------------------ data LProcess a = LP {lstep :: Writer [String] (Event a -> ([Event a], LProcess a))} ------------------------------------------------------------ exProcess2 :: ProcState -> Location -> LProcess EvtData exProcess2 pState loc = LP {lstep = xxx} where xxx = myStep pState myStep _ = return $ \(E t l _) -> ([E (t+1) l Wakeup], (proc' pState)) proc' state = exProcess2 (trc state) loc but when I replace xxx by myStep pState as in exProcess2 pState loc = LP {lstep = myStep pState} where xxx = myStep pState myStep _ = return $ \(E t l _) -> ([E (t+1) l Wakeup], (proc' pState)) proc' state = exProcess2 (trc state) loc I get No instance for (Monad m0) arising from a use of `myStep' The type variable `m0' is ambiguous Possible fix: add a type signature that fixes these type variable(s) It compiles again when I remove the xxx = line. Why is that so?

On Sun, Aug 10, 2014 at 2:20 PM, martin
but when I replace xxx by myStep pState as in
exProcess2 pState loc = LP {lstep = myStep pState} where xxx = myStep pState myStep _ = return $ \(E t l _) -> ([E (t+1) l Wakeup], (proc' pState)) proc' state = exProcess2 (trc state) loc
I get
No instance for (Monad m0) arising from a use of `myStep' The type variable `m0' is ambiguous Possible fix: add a type signature that fixes these type variable(s)
It compiles again when I remove the xxx = line. Why is that so?
It has to assign some kind of concrete type to `xxx`. If you are using it as in the example I elided, it has enough information to type it; if you do not have it at all, it obviously does not need to type it; if you define it but do not use it, it doesn't know it should ignore the definition (being an unused local binding, this is safe) and dies trying to infer a type for it anyway. Referential transparency is not involved (except perhaps incidentally). If there is a bug here, it is that it doesn't recognize that it should simply drop/ignore (with a warning) the definition of `xxx` because it's not reachable. Arguably, however, that is programmer error. -- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net

On 14-08-10 02:20 PM, martin wrote:
exProcess2 pState loc = LP {lstep = xxx} where xxx = myStep pState
vs
exProcess2 pState loc = LP {lstep = myStep pState} where xxx = myStep pState
The monomorphism restriction requires assigning a monomorphic (non-polymorphic) type to xxx. The assignment could come from declaring xxx's type (which you didn't do) or inferring from use sites (which you had in one example but not in another). When both are lacking, a job that needs done can't be done, and it is an error.

Am 08/10/2014 08:52 PM, schrieb Albert Y. C. Lai:
On 14-08-10 02:20 PM, martin wrote:
exProcess2 pState loc = LP {lstep = xxx} where xxx = myStep pState
vs
exProcess2 pState loc = LP {lstep = myStep pState} where xxx = myStep pState
The monomorphism restriction requires assigning a monomorphic (non-polymorphic) type to xxx. The assignment could come from declaring xxx's type (which you didn't do) or inferring from use sites (which you had in one example but not in another). When both are lacking, a job that needs done can't be done, and it is an error.
Very clear explanation. Thanks
participants (3)
-
Albert Y. C. Lai
-
Brandon Allbery
-
martin