Hugs appears to ignore definitions of ">>" when using "do" notation, perhaps relying on the default definition in terms of ">>=". Here is an example. According to the Haskell 98 Tutorial, the following two statements should be equivalent, right? main = do put "hello"; put "world" main' = put "hello" >> put "world" In the Hugs output below, it appears that they are not. % hugs TestDo __ __ __ __ ____ ___ _________________________________________ || || || || || || ||__ Hugs 98: Based on the Haskell 98 standard ||___|| ||__|| ||__|| __|| Copyright (c) 1994-2001 ||---|| ___|| World Wide Web: http://haskell.org/hugs || || Report bugs to: hugs-bugs@haskell.org || || Version: December 2001 _________________________________________ ... TestDo> run main hello
= world
TestDo> run main' hello
world
TestDo> :quit [Leaving Hugs] % cat TestDo.hs module TestDo where type State = [String] newtype MyMonad a = MyMonad (State -> (a, State)) instance Monad MyMonad where (MyMonad m) >>= fm = MyMonad $ \s -> let (x, s') = m s MyMonad m' = fm x s'' = ">>=" : s' in m' s'' (MyMonad m) >> (MyMonad m') = MyMonad $ \s -> let (_, s') = m s s'' = ">>":s' in m' s'' return x = MyMonad (\s -> (x, "return":s)) put x = MyMonad (\s -> (s, x:s)) get = MyMonad (\s -> (s,s)) run (MyMonad m) = let (_,s) = m [] s' = map putStrLn s in sequence_ (reverse s') main = do put "hello"; put "world" main' = put "hello" >> put "world" -- James B. White III (Trey) Center for Computational Sciences Oak Ridge National Laboratory whitejbiii@ornl.gov
"James B. White III (Trey)" wrote:
According to the Haskell 98 Tutorial, the following two statements should be equivalent, right?
main = do put "hello"; put "world"
main' = put "hello" >> put "world"
In the Hugs output below, it appears that they are not.
It looks like the problem is in "transDo" in "compiler.c". Both "FROMQUAL" and "DOQUAL" are defined in terms of "nameBind" (see below), where "nameBind" is defined in "type.c" as: nameBind = linkName(">>="); I think you need to define one or the other of these in terms of some new "Name" object, say "nameBind_", such that: nameBind_ = linkName(">>"); I don't understand the guts of Hugs enough to know how to make this change, or even which case needs the change. It looks like the right place is the "DOQUAL" block. Assuming I have "nameBind_" defined as above, can you describe the changes I should make to "transDo" to get it to use ">>" directly? /* -------------------------------------------------------------------------- * Translation of monad comprehensions written using do-notation: * * do { e } => e * do { p <- exp; qs } => LETREC _h p = do { qs } * _h _ = fail m "match fails" * IN bind m exp _h * do { LET decls; qs } => LETREC decls IN do { qs } * do { IF guard; qs } => if guard then do { qs } else fail m "guard fails" * do { e; qs } => LETREC _h _ = [ e | qs ] in bind m exp _h * * where m :: Monad f * ------------------------------------------------------------------------*/ static Cell local transDo(m,e,qs) /* Translate do { qs ; e } */ Cell m; Cell e; List qs; { if (nonNull(qs)) { Cell q = hd(qs); Cell qs1 = tl(qs); switch (fst(q)) { case FROMQUAL : { Cell ld = NIL; Cell hVar = inventVar(); if (!failFree(fst(snd(q)))) { Cell str = mkStr(findText("match fails")); ld = cons(pair(singleton(WILDCARD), ap2(nameMFail,m,str)), ld); } ld = cons(pair(singleton(fst(snd(q))), transDo(m,e,qs1)), ld); return ap(LETREC, pair(singleton(pair(hVar,ld)), ap(ap(ap(nameBind, m), translate(snd(snd(q)))), hVar))); } case DOQUAL : { Cell hVar = inventVar(); Cell ld = cons(pair(singleton(WILDCARD), transDo(m,e,qs1)), NIL); return ap(LETREC, pair(singleton(pair(hVar,ld)), ap(ap(ap(nameBind, m), translate(snd(q))), hVar))); } case QWHERE : return expandLetrec(ap(LETREC, pair(snd(q), transDo(m,e,qs1)))); case BOOLQUAL : return ap(COND, triple(translate(snd(q)), transDo(m,e,qs1), ap2(nameMFail,m, mkStr(findText("guard fails"))))); } } return e; } -- James B. White III (Trey) Center for Computational Sciences Oak Ridge National Laboratory whitejbiii@ornl.gov
"James B. White III (Trey)"
Hugs appears to ignore definitions of ">>" when using "do" notation, perhaps relying on the default definition in terms of ">>=". Here is an
example.
According to the Haskell 98 Tutorial, the following two statements should be equivalent, right?
main = do put "hello"; put "world"
main' = put "hello" >> put "world"
Hi, well observed & reported. To be very precise about this issue, the Haskell98 Report doesn't really fix the translation/desugaring rules for the "do" notation -- Section 3.14 presents a bunch of identities that hold for "do", but only suggests that these might be used by a Haskell system when desugaring "do" expressions. Both GHC and Hugs desugars "do{ e ; stmts }" as "e >>= \ _ -> do{stmts}", rather than "e >> do {stmts}", which explains the discrepancy between expected and actual output. Until the wording in the Report is either strengthened or GHC is also changed to use ">>" in the above, I'm reluctant to change Hugs right now. Anyway, that's my thinking - others might feel differently; I'm in no way in control of the Hugs sources. --sigbjorn
participants (2)
-
James B. White III (Trey) -
Sigbjorn Finne