Re: PATCH: implementation for TH PprLib.hs punctuate function
On Tue, Mar 02, 2004 at 07:02:18PM +, Duncan Coutts wrote: I noticed that the 6.3 version of the PprLib.hs is not fully implemented so pretty printing some things calls Prelude.undefined. Thanks - looks like something I forgot to go back to. Attached patch typechecks but I've not rebuilt yet so I've not tested it I've just used the punctuate text from Text.PrettyPrint.HughesPJ (but with refering to the monadic one now). Thanks Ian ___ Glasgow-haskell-bugs mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
RE: [Haskell] Per-type function namespaces (was: Data.Set whishes)
| detail, of course ;). What I'm secretly hoping is that the | GHC/hugs/HBC people will see what I'm trying to achieve, tell me I'm | totally nuts, and then suggest an alternative, much simpler approach | which gives us exactly the same goal ... As I implied earlier, I am thus far unconvinced that the complexity cost justifies the benefit. Let me suggest two simpler alternatives. Alternative 1 Given import FiniteMap( FM, add {- :: FM a b - a - b - FM a b -} ) and fm :: FM Int Bool, you want fm.add x y to mean the same as add fm x y (but in addition allow lots of unrelated 'add' functions) My objection is that the type of 'fm' is a matter of inference, whereas in Java it'd be a matter of explicit declaration. But you could adapt your story to be more explicit, thus FM.add fm x y The qualifier here is the *type* not the *module*. (Let's assume they share a name space for now.) This would work for record selectors too: data T = T { x::Int, y::Int } data S = S { x::Int, y::Int } Now f p q = T.x p + S.y q I guess the rule is that you can qualify a function by the name of the outermost type constructor of its first argument. I would restrict this only to functions with explicitly-declared types, so that there's no interaction with inference. Alternative 2 If the big bug-bear is record selectors, let's focus on them exclusively. I now think that ML got it right. ML records are simply labelled tuples. So just as (Bool,Int) is an anonymous type, so is {x::Bool, y::Int}. Indeed (Bool,Int) is just shorthand for {#1::Bool, #2::Int}. In Haskell, a function with a tuple argument takes exactly that tuple: f :: (Bool,Int) - Bool f (x,y) = x Here, f cannot take a 3-tuple or a 89-tuple. In ML it's the same with records (I'm not getting the ML syntax right, but you'll get the idea): f :: {x::Bool, y::Int} - Bool f r = r.x Here f cannot take a record of shape other than {x::Bool,y::Int}. You are allowed to write f {x, ...} = x but you must then explain f's argument type separately. For example you can write f :: {x::Bool, p::String, q::Bool} - Bool f {x, ...} = x So there is no sub-typing, no row polymorphism, no attempt to give f r = r.x a fancy type that makes f applicable to any record with an x field. On the other hand, there is also no problem with many records having the same field name either, which is the problem we started with. There are no implicitly-defined record selectors either: you have to use pattern matching for that. My personal view is this: we should have adopted the ML view of records. It solves the immediate problem, and no more elaborate scheme seems sufficiently right to be declared the winner.Alas, like all other proposals, it's not backward compatible, and hence not likely to fly. Simon ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
RE: [Haskell] Per-type function namespaces (was: Data.Set whishes)
| So there is no sub-typing, no row polymorphism, no attempt to give | f r = r.x | a fancy type that makes f applicable to any record with an x field. | | On the other hand, there is also no problem with many records having the | same field name either, which is the problem we started with. There are | no implicitly-defined record selectors either: you have to use pattern | matching for that. Andreas says: | Actually, #l is just syntactic sugar for (\{l=x,...}-x), which implies | that you might need type annotations. Yes I was wrong to say that there are no implicitly-defined record selectors; (#l r) is exactly that. Syntactically I'd prefer (r.l); but regardless, it's a syntactic construct distinct from function application, which must be monomorphic. Yes, that's a kind of interaction between binding and type system (of the kind I objected to) but a very weak and well-behaved kind of interaction. Simon ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: [Haskell] Per-type function namespaces (was: Data.Set whishes)
Simon Peyton-Jones wrote: If the big bug-bear is record selectors, let's focus on them exclusively. I now think that ML got it right. ML records are simply labelled tuples. Note that this is true only for SML, not for Caml. So just as (Bool,Int) is an anonymous type, so is {x::Bool, y::Int}. Indeed (Bool,Int) is just shorthand for {#1::Bool, #2::Int}. A bit of nitpicking: (Bool,Int) would be shorthand for {1::Bool,2::Int}. In SML, labels may be numeric or alpha-numeric. OTOH, the hash is the projection operator (ASCII art for \pi), which can be used for both kinds of labels: #2 (x,y,z) #b {a=x, b=y, c=z} Actually, #l is just syntactic sugar for (\{l=x,...}-x), which implies that you might need type annotations. There are no implicitly-defined record selectors either: you have to use pattern matching for that. Or projection using #. Cheers, - Andreas -- Andreas Rossberg, [EMAIL PROTECTED] Let's get rid of those possible thingies! -- TB ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: [Haskell] Per-type function namespaces (was: Data.Set whishes)
Simon Peyton-Jones wrote: | Actually, #l is just syntactic sugar for (\{l=x,...}-x), which implies | that you might need type annotations. Yes I was wrong to say that there are no implicitly-defined record selectors; (#l r) is exactly that. Syntactically I'd prefer (r.l); but regardless, it's a syntactic construct distinct from function application, which must be monomorphic. I'm not sure I parsed your sentence correctly, but in SML, (#l r) indeed *is* a function application, and #l is a perfectly normal function, as its desugared form reveals. It just fails to have a principal type (due to the lack of row polymorphism), so its type must be derivable from context - which might involve a type annotation. BTW, I'd prefer r.l as well. A section like (.l) could then give you the equivalent of #l. - Andreas -- Andreas Rossberg, [EMAIL PROTECTED] Let's get rid of those possible thingies! -- TB ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: [Haskell] Per-type function namespaces (was: Data.Set whishes)
On Thu, Mar 04, 2004 at 09:21:23AM -, Simon Peyton-Jones wrote: My personal view is this: we should have adopted the ML view of records. It solves the immediate problem, and no more elaborate scheme seems sufficiently right to be declared the winner.Alas, like all other proposals, it's not backward compatible, and hence not likely to fly. About a year ago, you were toying with a simple polymorphic system with just has predicates. If these were automatically derived, it seems you'd get something quite close to backward compatible, except for the pesky extra lifting in record types, and not being able to omit fields when constructing the record. (And update might not statically check that all fields belong to the same constructor, for the simple version of the type system.) Is that just too clunky? ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
[Haskell] GHC EXE Windows
GHC executable file only works in MS-DOS. I would like run the executable file on Windows. Can someone help meThanks ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: [Haskell] Per-type function namespaces (was: Data.Set whishes)
Hi While we're talking about SML, I think there are a few other things worth stealing... 1) I still miss multiline pattern matching in lambda (fn p1 = e1 | p2 = e2 | ...) not strictly necessary, but often less disruptive of the text than either a let/where-introduced helper-function or \ x - case x of ... especially when there's more than one argument. Doubtless there's some deep reason why Haskell doesn't have these that I'm too young to remember. 2) I miss local implementation-decls in interface-decls end Is there some fabulous layout rule for `where' clauses that means the same thing? 3) I miss `open' from the module system. This allows let open Structure in expression end local open Structure in declarations end reducing your program's acne. I often wonder why the OO world has no room for Pascal's lovely old `with ... do ...'. [Pascal even had variant records with case expressions: it wasn't remotely type-safe, but it looked like datatypes. What happened to them? Programmers like sums, but software engineers like products...] Haskell already has per-module namespaces; everything has a unique long name; good start. Now what we need is more control over the meaning of short names. Could we have local opening of (already imported) modules, simply rebinding the relevant short names in their scope? You'd get the localized namespace you might want at the cost of one scoped declaration, rather than a zillion projections. And while we're at it... Simon Peyton-Jones wrote: If the big bug-bear is record selectors, let's focus on them exclusively. I now think that ML got it right. ML records are simply labelled tuples. The pattern-matching was always dreadful, especially if you just wanted to tweak one field, but I expect that could be dealt with. Andreas Rossberg wrote: Note that this is true only for SML, not for Caml. So just as (Bool,Int) is an anonymous type, so is {x::Bool, y::Int}. Indeed (Bool,Int) is just shorthand for {#1::Bool, #2::Int}. A bit of nitpicking: (Bool,Int) would be shorthand for {1::Bool,2::Int}. In SML, labels may be numeric or alpha-numeric. OTOH, the hash is the projection operator (ASCII art for \pi), which can be used for both kinds of labels: #2 (x,y,z) #b {a=x, b=y, c=z} Actually, #l is just syntactic sugar for (\{l=x,...}-x), which implies that you might need type annotations. That's a neat piece of syntax, but if you're willing to look at types, you might be able to introduce an opening operator for records, | say, at the cost of restricting field labels to being valid names. ie if r :: {a::A, b::B, c::C} r | e means let {a=a,b=b,c=c} = r in e Again, the usual projection is a special case. No reason why you couldn't use this opening notation for the existing field-labelled datatypes. OK, you'd be shadowing projection functions with field names, but that's not so shocking. This opens a further, if questionable, possibility, viz data MyQuad = MyQuad {a::Int, b::Int, c::Int} | f x = (a * x + b) * x + c declaring a computed field f for that constructor. As usual, only your conscience prevents you misusing this facility in a multi-constructor type. For backward compatibility, you'd need to leave a, b and c as global names, but you could choose to make f accessible only on opening. That leaves open the possibility of data MyQuad = MyQuad {globa::Int, globb::Int, globc::Int} | a = globa b = globb c = globc f :: Int - Int f x = (a * x + b) * x + c which I'm sure could be sugared to data MyQuad = MyQuad {| a::Int, | b::Int, | c::Int} | f :: Int - Int f x = (a * x + b) * x + c meaning that the fields should not have global names, only local names on opening. Or one could add `methods' to the whole type, being functions on that type, defined by pattern matching, but with one argument left of | data Fred = F1 | F2 | F3 with cycle :: Fred F1 | cycle = F2 F2 | cycle = F3 F3 | cycle = F1 Again, cycle wouldn't be globally declared. Goodness me, it's a per-type namespace, but not for `ordinary' application. There's a catch, of course. When you write r | e you give the typechecker no clue as to the type of r: it just has to infer the type of r and hope it's a datatype. I suggest this is perfectly sustainable, given that (1) your function already has a top-level type signature, hasn't it? (2) this sort of thing happens all the time with ad-hoc polymorphism anyway; when you have class Blah x where blah :: x - x instance Blah (Maybe Int) where blah Nothing = Just 0 blah (Just x) = Just (x + 1) what's blah Nothing ? Is this plausible? Conor ___ Haskell mailing list [EMAIL
[Haskell] natural numbers
hello, looking through the documentation for Data.Word I run into the follwoing comment: it would be very natural to add a type Natural providing an unbounded size unsigned integer, just as Integer provides unbounded size signed integers. We do not do that yet since there is no demand for it. if that is not too much work could we have that in the library? i think it would be very useful. (i am trying to generate demand :-) it would also be useful to have finite natural numbers, ala C's unsigned int. -iavor -- == | Iavor S. Diatchki, Ph.D. student | | Department of Computer Science and Engineering | | School of OGI at OHSU | | http://www.cse.ogi.edu/~diatchki | == ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: [Haskell] natural numbers
it would also be useful to have finite natural numbers, ala C's unsigned int. Word8, Word16, Word32 and Word64 -- Alastair Reid www.haskell-consulting.com ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: [Haskell] natural numbers
it would be very natural to add a type Natural providing an unbounded size unsigned integer, just as Integer provides unbounded size signed integers. We do not do that yet since there is no demand for it. if that is not too much work could we have that in the library? i think it would be very useful. (i am trying to generate demand :-) In my courses here in Argentina we have used a type Natural for pedagogical purposes. It has some ugly features regarding negative constants (their meaning is bottom), but it gives young students the feeling that factorial, fibonacci and other functions that are more natural over natural numbers have the right type. I attach my implementation, in case it may be useful to someone. Pablo E. Martínez López (Fidel) -- Author: Pablo E. Martínez López -- University of La Plata and University of Buenos Aires, Argentina -- [EMAIL PROTECTED] -- Date: Sep 2000 module Nat (Nat) where data Nat = N Integer -- N is hidden -- These numbers are used as any other (including numeric constants) -- thanks to the class system. -- The check about the naturality of the number is done in runtime, in -- the construction of the representation. -- For that reason, eg. (2-3) :: Nat has the right type, but gives an -- error if it is evaluated. -- At Universities of Buenos Aires and La Plata we use them for pedagogical -- purposes, so that functions like factorial or fibonacci can be given a -- type involving Nats and not Integers. -- Internal constructor (runtime check) nat :: Integer - Nat nat n = if n=0 then N n else error (show n ++ is not a natural number!) -- The instances of all the classes instance Eq Nat where (N n) == (N m) = n==m instance Ord Nat where (N n) = (N m) = n = m instance Enum Nat where fromEnum (N n) = fromEnum n toEnum n = nat (toEnum n) instance Num Nat where (N n) + (N m) = nat (n+m) (N n) - (N m) = nat (n-m) (N n) * (N m) = nat (n*m) negate (N n) = error A natural number cannot be inverted! abs n = n signum (N n) = nat (signum n) fromInteger n = nat n instance Show Nat where showsPrec p (N n) = showsPrec p n instance Read Nat where readsPrec p s = [ (nat n, s') | (n,s') - readsPrec p s ] instance Real Nat where toRational (N n) = toRational n instance Integral Nat where quot (N n) (N m) = nat (quot n m) rem (N n) (N m) = nat (rem n m) div (N n) (N m) = nat (div n m) mod (N n) (N m) = nat (mod n m) quotRem (N n) (N m) = let (q,r) = quotRem n m in (nat q, nat r) divMod (N n) (N m) = let (q,r) = divMod n m in (nat q, nat r) toInteger (N n) = n ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: [Haskell-cafe] State Monad
Hi, thanks for your suggestion. The thing is, that I don't want to change the type of my transformation functions. To answer Iavor's question: I have basically two types of transformation functions. One StringTransformation (String - String) and one transformation with a string and something (e.g. random generator) ((a,String) - (a,String)). The vast majority of transformation I use are from the first type. I was looking for a nice way to write this in a the compact style. I haven't thought about exceptions yet. My current approach is as follows: withString :: String - State String () - String withString state monad = execState monad state withStringAndT :: String - t - StateT t (State String) () - String withStringAndT state t monad = execState (execStateT monad t) state modifyT :: ((t, String) - (t, String)) - StateT t (State String) () modifyT trans = do s - lift get t - get let (t', s') = trans (t, s) lift (put s') put t' now I can use either let str' = withString str $ do modify $ foo_stringtrans modify $ bar_stringtrans or let str' = withStringAndT str (gen) $ do modifyT $ foo_stringgentrans lift $ modify $ foo_stringtrans Cheers, Georg On Thu, 04 Mar 2004 08:51:04 +1300, Tom Pledger [EMAIL PROTECTED] wrote: Georg Martius wrote: [...] I could write: modifyT :: ((a, String) - (a, String)) - a - State String a modifyT trans a = do str - get let (a', str') = trans (a, str) put str' return a' f :: State String () f = do put hallo modify strTrans i - modifyT strIntTrans 4-- strIntTrans :: (Int, String) - (Int, String) i' - modifyT strIntTrans i... But this is obviously awkward. [...] Hi. People have already replied about the state monad aspect, but there's another small improvement I'd like to suggest. Look at what modifyT does with 'trans' and 'a'. They are always used together. So, how about combining them *outside* the definition of modifyT? modifyT :: (String - (a, String)) - State String a modifyT trans = do (a, s) - gets trans put s return a f = do ... i - modifyT (strIntTrans 4) -- strIntTrans :: Int - String - (Int, String) i' - modifyT (strIntTrans i) ... Aside: if you rewrite ($) similarly, you get id. Regards, Tom ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe