Re: Design patterns in Haskell
I spent an awful lot of time doing a brain-dump into these pages and am a bit dissapointed that they seemed to have dissappeared without trace. Were these archived anywhere Keith Wansbrough [EMAIL PROTECTED] Sent by: [EMAIL PROTECTED] 03/12/2002 18:02 To:matt hellige [EMAIL PROTECTED] cc:[EMAIL PROTECTED], (bcc: Chris Angus/Lawson) Subject:Re: Design patterns in Haskell size. while there's really no substitute for experience, i really believe we could benefit from some patterns. There was a list of design patterns for Haskell on the Wiki (back in the days when it worked): http://haskell.org/wiki/wiki?CommonHaskellIdioms --KW 8-) -- Keith Wansbrough [EMAIL PROTECTED] http://www.cl.cam.ac.uk/users/kw217/ University of Cambridge Computer Laboratory. ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
(no subject)
Does anyone know what happened to the wiki on haskell.org? There was lots of stuff there last year (mostly to do with design patterns) which seems to have been lost. Some of the links are still there but they don't go anywhere. Cheers Chris
RE: String manipulation.
Title: RE: String manipulation. You may want to use reads as read will call error if the string is not an integer or use something akin to the example below readMaybeInt :: String - Maybe Int readMaybeInt s = case reads s of [(x,_)] - Just x _ - Nothing -Original Message- From: Hal Daume III [mailto:[EMAIL PROTECTED]] Sent: 07 February 2002 17:54 To: DK Cc: [EMAIL PROTECTED] Subject: Re: String manipulation. You should have a look at the Read class. A member a of the Read class has a function read :: String - a. so, for example, you can say: (read 5.0) :: Double to read this as a double. You could also read it as an integer or something. If you have a list of strings that you want to convert to a list of integers, you could do: map (\x - (read x)::Double) [list of strings] Hope that helps. - Hal -- Hal Daume III Computer science is no more about computers | [EMAIL PROTECTED] than astronomy is about telescopes. -Dijkstra | www.isi.edu/~hdaume On Thu, 7 Feb 2002, DK wrote: Hello. First of all I am a beginner in Haskell, and I must confess I do not yet fully understand it. I need to write a program in Haskell, though, and I am having some difficulties... What I would like to ask, is how can I take a string from a list, and manipulate it, in order to convert it to an integer. Any help would be very appreciated. Thank you very much, Dimitris ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
RE: Implicit Parameters
Title: RE: Implicit Parameters I'm obviously missing something here. I dont understand what monomorphism has to do with the given example as the implicit parameter would be the same type [a] for some type a in each case. If we made the parameter explicit then removing the type definition would not cause this problem. Are implicit parameters not simply made explict by the compiler? -Original Message- From: John Hughes [mailto:[EMAIL PROTECTED]] Sent: 04 February 2002 10:26 To: [EMAIL PROTECTED]; [EMAIL PROTECTED] Subject: Re: Implicit Parameters Suppose I have the following function definition: app :: (?ys :: [a]) = [a] - [a] app xs = case ?ys of [] - xs (y:ys') - y : (app xs with ?ys = ys') This function appends its argument to its implicit argument, by recursively changing the implicit argument. For example: Hugs app [1,2] with ?ys = [3,4] [3,4,1,2] So far so good! Now, since Haskell has type inference, we can leave out the type signature: -- app :: (?ys :: [a]) = [a] - [a] app xs = case ?ys of [] - xs (y:ys') - y : (app xs with ?ys = ys') Let us check if it still works again: Hugs app [1,2] with ?ys = [3,4] [3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,{Interrupted!} And, stunningly, it doesn't! Why doesn't this work? That is because type inference assumes that the body of `app' is monomorphic, i.e. has no context in its type. Therefore, the recursive call to app where ?ys is changed, had no effect at all. It works with the type signature there, because in order to implement type checking (note: not type inference) with polymorphic recursion demands to use the stated type in checking the body of the function. Mark Shields, Simon Peyton-Jones, and I, and also Jörgen Gustavsson have been discussing several modest solutions to this (we believe it is not needed to do full type inference that can deal with polymorphic recursion to solve this problem). Not so fast! Proposing a solution means this is regarded as a problem! But what is to say that the first behaviour is right in any general sense? The important thing is that the language semantics is clear, and this is a semantic question. The static semantics of Haskell *is* clear: recursive calls are monomorphic unless a type signature is given; this is the basis for understanding the behaviour above. When implicit parameters are used, it's very important to be aware whether a binding is monomorphic or not (can't resist plugging := again!). Will your solution make understanding when a binding is monomorphic simpler? If not, it could be worse than the problem -- and the fact that it makes this one example behave as you want is no justification. John ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
RE: Help using a state monad
Title: RE: Help using a state monad your pattern match of (s:sx) seems to be the cause of the delay try --Process the input mProcess :: String - State String mProcess sx = do b - isOn if ( head sx == 't' ) then toggle else return () appOut (tuUpper b (head sx)) (mProcess (tail sx)) instead -Original Message- From: Tom Bevan [mailto:[EMAIL PROTECTED]] Sent: 14 January 2002 05:58 To: Haskell Cafe List Subject: Help using a state monad Hi all, I'm trying to get a feel for how monads might be used in a Haskell program and develop an approach that would be useful for larger projects. I have tried to model in miniture a programme which takes input from 'standard in' and processes it against an internal state and then returns the processed result to 'standard out'. My problem is that, becuase of the way I have constructed the programme 'standard out' lags behind by one character. I'm hoping that someone might have a better design they could share with me. Tom.
RE: Question about hugs´s DEBUG_SHOWSC
is this not the dictionary passing (or whatever)to achieve overloading. -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] Sent: 13 April 2001 06:48 To: [EMAIL PROTECTED] Cc: [EMAIL PROTECTED]; [EMAIL PROTECTED] Subject: Question about hugss DEBUG_SHOWSC hi haskellers ... Im trying to use the hugss flag DEBUG_SHOWSC. Everything seems to work fine, except for one(simple?) detail: When you use Int or Double literals, hugs always add extra variables, related to the fromInt/fromDouble aplication. For example: f = 666 should be translated to: f = fromInt 666 but hugs returns : f = fromInt v35 666 What is the var. v35 for???, the function fromInt receives just one argument. If the function has parameters, the resulting function has extra-parameters, which seems to be out-of-place in both sides of the binding ... here you are a couple of examples: the function: f x = 666 generates the output: f o2 o1 = fromInt o2 666 And the reported type for f is: Num a = b - a , which is inconsistent with the previous result. the function: f x = 666 + x generates : f o2 o1 = (+) o2 (fromInt o2 666) o1 which has similar troubles to the previous example. What are these extra-variables for? Are they a debug-feature? whats the meaning? And finally, the obligated question: how can I avoid them? I suppose that I have to take a look at the source code, but: whatd be the part which is responsible for this(parser,static,type... no please,compiler)? Thanks in advance. saludos dario estepario ... - Obtn tu correo en www.correo.unam.mx UNAMonos Comunicndonos ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
RE: Please help me
Faizan, A clue is to use list comprehensions (which are very like ZF set notation) First think how you would define a cartesian product in set notation X x Y x Z = {(x,y,z) | ...} and then think how this is written in list comprehension notation Chris -Original Message- From: FAIZAN RAZA [mailto:[EMAIL PROTECTED]] Sent: 08 February 2001 13:49 To: [EMAIL PROTECTED] Subject: Please help me Hello Please help me to solve this questions Question Cartesian Product of three sets, written as X x Y x Z is defined as the set of all ordered triples such that the first element is a member of X, the second is member of Y, and the thrid member of set Z. write a Haskell function cartesianProduct which when given three lists (to represent three sets) of integers returns a list of lists of ordered triples. For examples, cartesianProduct [1,3][2,4][5,6] returns [[1,2,5],[1,2,6],[1,4,5],[1,4,6],[3,2,5],[3,2,6],[3,4,5],[3,4,6]] Please send me reply as soon as possible Ok I wish you all the best of luck ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: Imperative Object Destruction
why not create an abstract datatype OpenFile a which is a monad data OpenFile a = OpenFile (Maybe FileHandle - IO a) and create you operations in terms of this openFile :: String - OpenFile () count:: OpenFile Int read :: Int - OpenFile [Byte] then you could habe a run function runOF :: OpenFile a - IO a which ran whatever you wanted for the file and ensured tahthe file was closed correctly afterwards. How we would do this with 2 files however I'm not so sure. -Original Message- From: Ashley Yakeley [mailto:[EMAIL PROTECTED]] Sent: 13 November 2000 07:21 To: Haskell List Subject: Imperative Object Destruction C++ provides a convenient mechanism for cleaning up stuff, the destructor, which is guaranteed to get called when an object passes out of scope (or something). I'm wondering how to make a Haskell equivalent for imperative code. For instance, consider a simple file API, with these operations: open: given a string (the filename), open an existing file with that name, return a file-handle (or fail) count: given a file-handle, get the length of the file read: given a file-handle, offset into the file and a number of bytes, read the file returning a list of bytes (or fail) write: given a file-handle, offset into the file and a list of bytes, write the bytes to the file at the offset close: given a file-handle, close the handle In C++ I could simply create an OpenFile class, with the close operation in the destructor. The actual operations would be hidden from OpenFile's clients. I'd like to represent this API in Haskell so that the type-rules guarantee that in any imperative action of type 'IO a', 1. every opened file gets closed exactly once 2. no read or write operations are performed on file-handles that have not yet been opened, or that have already been closed. My first guess was to create a function that encapsulated the entire life-cycle of the file, passing in a function that would represent whatever one wished to do on the file: count :: Handle - IO Integer read :: (Integer,Integer) - Handle - IO [Byte] write :: (Integer,[Byte]) - Handle - IO () withFile :: (Handle - IO a) - String - IO a 'withFile operation name' would open the file called 'name', perform the operation 'operation', and then close the file. So for instance, to get the length of a file named "/home/ashley/foo": withFile count "/home/ashley/foo" Trouble is, one can easily pass a return function to withFile to get ahold of the handle after it's been closed. My second guess was to use a special type to represent an imperative operation that needed a handle: read :: (Integer,Integer) - HandleOperation [Byte] write :: (Integer,[Byte]) - HandleOperation () withFile :: HandleOperation a - String - IO a Of course, I'd then need to provide functions to compose/concatenate HandleOperation values. But I can't help thinking this problem is already well-known and there's a straightforward solution... -- Ashley Yakeley, Seattle WA ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
RE: Extensible data types?
How about defining a Datatype Fn which defines all functions and building in terms of this data Expr = Int Integer | Cte String | Var String | App Fn [Expr] deriving (Show) data Fn = Fn String | Combiner String | Compose Fn Fn deriving (Show) class (Show a) = Fns a where mkFn :: a - Fn mkFn x = Fn (show x) data Basic = Negate deriving (Show) data Combining = Sum | Prod deriving (Show) data Trig = Sin | Cos | Tan deriving (Show) instance Fns Trig instance Fns Basic instance Fns Combining where mkFn x = Combiner (show x) sine= mkFn Sin cosine = mkFn Cos tangent = mkFn Tan neg = mkFn Negate compose :: Fn - Fn - Fn compose x y = Compose x y match (Fn x) (Fn y) = x == y match (Combiner x) (Combiner y) = x == y match (Compose x y) (Compose a b) = match x a ma match _ _ = False diff :: Fn - Fn diff fn | match fn sine = cosine diff fn | match fn cosine = neg `compose` cosine -Original Message- From: Jose Romildo Malaquias [mailto:[EMAIL PROTECTED]] Sent: 25 September 2000 12:14 To: Chris Angus Cc: [EMAIL PROTECTED] Subject: Re: Extensible data types? On Mon, Sep 25, 2000 at 11:37:24AM +0100, Chris Angus wrote: I've not seen this before, out of interest, why would you want/need such a thing? Is there any Haskell implementation that supports extensible data types, in which new value constructors can be added to a previously declared data type, like data Fn = Sum | Pro | Pow ... extend data Fn = Sin | Cos | Tan where first the Fn datatype had only three values, (Sum, Pro and Pow) but later it was extended with three new values (Sin, Cos and Tan)? I want this to make a system I am workin on flexible. Without it, my system is going to be too rigid. I am working on an Computer Algebra system to transform mathematic expressions, possibly simplifing them. There is a data type to represent the expressions: data Expr = Int Integer | Cte String | Var String | App Fn [Expr] An expression may be an integer, a named constante (to represent "known" contantes like pi and e), a variable or an application. An application has a functor (function name) and a list of arguments. The functor is introduced with data Fn = Sum | Pro | Pow meaning the application may be a sum, a product or a power. The project should be modular. So there are modules to deal with the basic arithmetic and algebraic transformations involving expressions of the type above. But there are optional modules to deal with trigonometric expressions, logarithms, vectors, matrices, derivatives, integrals, equation solving, and so on. These should be available as a library where the programmer will choose what he needs in his application, and he should be able to define new ones to extend the library. So these modules will certainly need to extend the bassic types above. If it is really impossible (theoriticaly or not implemented) then I will have to try other ways to implement the idea. The functions manipulating the expressions also should be extensible to accomodate new algorithms. The extensions is in a form of hooks (based on the Fn component of an application function) in the main algorithms. Romildo -- Prof. José Romildo Malaquias [EMAIL PROTECTED] Departamento de Computação Universidade Federal de Ouro Preto Brasil
SAX, XML, Haskell
Hi, I looked at HaXml a while ago and it seemed to offer a very Dom-like interface. I was wondering if anyone had thought of making a Sax-like interface based on lazy evaluation. where tokens are processed and taken from a (potentially) infinite stream Chris
RE: Extensible data types?
Just wondering if you'd seen the dynamic datatype which basically gives you an "Any" in ghc/hugs -Original Message- From: Jose Romildo Malaquias [mailto:[EMAIL PROTECTED]] Sent: 25 September 2000 12:14 To: Chris Angus Cc: [EMAIL PROTECTED] Subject: Re: Extensible data types? On Mon, Sep 25, 2000 at 11:37:24AM +0100, Chris Angus wrote: I've not seen this before, out of interest, why would you want/need such a thing? Is there any Haskell implementation that supports extensible data types, in which new value constructors can be added to a previously declared data type, like data Fn = Sum | Pro | Pow ... extend data Fn = Sin | Cos | Tan where first the Fn datatype had only three values, (Sum, Pro and Pow) but later it was extended with three new values (Sin, Cos and Tan)? I want this to make a system I am workin on flexible. Without it, my system is going to be too rigid. I am working on an Computer Algebra system to transform mathematic expressions, possibly simplifing them. There is a data type to represent the expressions: data Expr = Int Integer | Cte String | Var String | App Fn [Expr] An expression may be an integer, a named constante (to represent "known" contantes like pi and e), a variable or an application. An application has a functor (function name) and a list of arguments. The functor is introduced with data Fn = Sum | Pro | Pow meaning the application may be a sum, a product or a power. The project should be modular. So there are modules to deal with the basic arithmetic and algebraic transformations involving expressions of the type above. But there are optional modules to deal with trigonometric expressions, logarithms, vectors, matrices, derivatives, integrals, equation solving, and so on. These should be available as a library where the programmer will choose what he needs in his application, and he should be able to define new ones to extend the library. So these modules will certainly need to extend the bassic types above. If it is really impossible (theoriticaly or not implemented) then I will have to try other ways to implement the idea. The functions manipulating the expressions also should be extensible to accomodate new algorithms. The extensions is in a form of hooks (based on the Fn component of an application function) in the main algorithms. Romildo -- Prof. José Romildo Malaquias [EMAIL PROTECTED] Departamento de Computação Universidade Federal de Ouro Preto Brasil
RE: Extensible data types?
Presumably this means differentiation/integeration would have to be typed as diff :: (FnExt a,FnExt b) = a - b Chris -Original Message- From: Peter Achten [mailto:[EMAIL PROTECTED]] Sent: 25 September 2000 23:34 To: Jose Romildo Malaquias Cc: [EMAIL PROTECTED] Subject: Re: Extensible data types? At 07:46 25-9-00 -0300, Prof. José Romildo Malaquias wrote: Hello. Is there any Haskell implementation that supports extensible data types, in which new value constructors can be added to a previously declared data type, like data Fn = Sum | Pro | Pow ... extend data Fn = Sin | Cos | Tan where first the Fn datatype had only three values, (Sum, Pro and Pow) but later it was extended with three new values (Sin, Cos and Tan)? What are the pointers to documentation on such kind of extensions to Haskell? In the Clean Object I/O library we encountered a similar challenge and solved it using type constructor classes. The solution can also be used in Haskell. The basic idea is as follows: (1) For each type constructor that has to be extensible you introduce a type constructor class; (2) For each of the data constructors of such type constructors you introduce a new type constructor (reusing their name is very convenient); (3) For each such new type constructor define it as an instance of the type constructor class that was created from its parent type constructor. Example: (1) From type constructor Fn you create: class FnExt where ... -- Define your class member functions here (2) From the data constructors Sum | Pro | Pow you create: data Sum = Sum data Pro = Pro data Pow = Pow (3) For each newly defined type constructor in (2) you define an instance: instance FnExt Sum instance FnExt Pro instance FnExt Pow All of your functions that previously were defined on Fn are now overloaded functions: fun :: ... Fn ... - ... Fn ... becomes: fun :: (FnExt fn) = ... fn ... - ... fn ... I hope you find this scheme useful. I guess its applicability depends on your particular class member functions and program. Regards, Peter Achten = References: although the perspective in the Clean Object I/O library is on the data structures with generic interpretation functions, the technique is basically the same as described here. In my PhD Thesis you can find an early reference: * The reference: Achten, P.M. Interactive Functional Programs - Models, Methods, and Implementation. PhD thesis, University of Nijmegen, 1996. * The abstract at: http://www.cs.kun.nl/~peter88/PeterThesisCh6.html * The chapter at: ftp://ftp.cs.kun.nl/pub/CSI/SoftwEng.FunctLang/papers/achp96-t hesis6.ps.gz A more modern version can be found here: * The reference: Achten, P.M. and Plasmeijer, M.J. Interactive Functional Objects in Clean. In Clack, C., Hammond, K., and Davie, T. eds., Proceedings 9th International Workshop Implementation of Functional Languages, IFL'97, St.Andrews, Scotland, UK, September 1997, selected papers, LNCS 1467, Springer, pp. 304-321. * The abstract at: ftp://ftp.cs.kun.nl/pub/Clean/papers/1998/achp97-InteractFuncObjects.abs * The paper at: ftp://ftp.cs.kun.nl/pub/Clean/papers/1998/achp97-InteractFuncObjects.ps.gz
RE: Patterns Catalog
I have thought of a few "functional patterns" ... there may be repeats in these as they were rattled off last night when I was half asleep. I must have missed some though ... anyone? *) higher order functions (Abstraction) *) Circular programming *) Information hiding (combinators ... Monads) *) Pipelining functions *) Propogation of state (backwards) *) Non-determinism *) Intermediate representation (Pretty printer) *) Exception monad (Can be viewed as null object in that we need not constantly check for failure) *) State monad *) Iteration (flatten to list and process) *) Functional dispatch (pattern match and carry out work in separate fns) *) Memoise functions by using CAF arrays *) Domain-specific processing (Little language) *) Phantom types *) Specialist data structure (Using Split lists rather than lists etc) *) Null object (fail) *) Unit object (return just)) *) Decoration [transform one structure into another] (possibly use polymorphism to make strcutures the same but parameterised) *) (Concrete type-instantiation [Debugging]) *) abstract datatyping (monads) *) Decouple pattern matching (arg1 then arg2 etc)[Chain of resonsibility] *) Worker / wrapper pairing *) Simulation (if haskell cannot do it then simulate this as little language that can) *) Return Maybe x rather than x and error as we can unwrap Maybe a into a but not vice versa *) Hints (strictify , dump state and continue) *) Intermediate form (create syntax tree rather than string) chain of responsibility *) Non-trivial type synonyms i.e. data Miles = Miles Int rather than type Miles = Int can remove later anyway -Original Message----- From: Chris Angus [mailto:[EMAIL PROTECTED]] Sent: 11 September 2000 08:48 To: 'Doug Ransom'; [EMAIL PROTECTED] Subject: RE: Patterns Catalog I've thought of this too. but I dont think there is anything out there which fits the bill. [I'd love someone to please correct me] btw for any folks out there who are thinking what the are patterns? http://www.enteract.com/~bradapp/docs/patterns-intro.html I think it would be a good thing to organise if anyone is willing to look ta this (If no-one is interested/ would rather do this) that person could be me as long as folk don't mind waiting a while for results. One obvious set of "patterns" could be thought of as the use of different monads. Unless anyone else wishes to be the contact point for this (Doug?) I suggest that if anyone has identified a functional pattern to email a brief set of details to (intially) me and I will either put hem together / forward them. For a starter we could have *) Using a monad to hide structure code in such a way as parameters are passed implicitly *) circular programming -Original Message- From: Doug Ransom [mailto:[EMAIL PROTECTED]] Sent: 08 September 2000 21:04 To: [EMAIL PROTECTED] Subject: Patterns Catalog I have worked through "Haskell: The craft of functional programming". Learning the language is one thing, applying FP is another. The next thing I would like to study would be a catalog of patterns for lazy functional programming. In the Object-oriented world, there are some catalogs of useful program techniques. I would like to know if there is anything like that in the Haskell/Functional Programming world. It is not clear to me when and how to use higher-ordereredness outside of map, filter, some partial applications and simple lambda expressions to be used in the above. Is there a catalog of patterns or some other book useful in becoming a skilled functional programmer?
RE: Patterns Catalog
I've thought of this too. but I dont think there is anything out there which fits the bill. [I'd love someone to please correct me] btw for any folks out there who are thinking what the are patterns? http://www.enteract.com/~bradapp/docs/patterns-intro.html I think it would be a good thing to organise if anyone is willing to look ta this (If no-one is interested/ would rather do this) that person could be me as long as folk don't mind waiting a while for results. One obvious set of "patterns" could be thought of as the use of different monads. Unless anyone else wishes to be the contact point for this (Doug?) I suggest that if anyone has identified a functional pattern to email a brief set of details to (intially) me and I will either put hem together / forward them. For a starter we could have *) Using a monad to hide structure code in such a way as parameters are passed implicitly *) circular programming -Original Message- From: Doug Ransom [mailto:[EMAIL PROTECTED]] Sent: 08 September 2000 21:04 To: [EMAIL PROTECTED] Subject: Patterns Catalog I have worked through "Haskell: The craft of functional programming". Learning the language is one thing, applying FP is another. The next thing I would like to study would be a catalog of patterns for lazy functional programming. In the Object-oriented world, there are some catalogs of useful program techniques. I would like to know if there is anything like that in the Haskell/Functional Programming world. It is not clear to me when and how to use higher-ordereredness outside of map, filter, some partial applications and simple lambda expressions to be used in the above. Is there a catalog of patterns or some other book useful in becoming a skilled functional programmer?
RE: Inferring types
-Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] Sent: 08 September 2000 17:17 To: [EMAIL PROTECTED] Subject: Re: Inferring types Sat, 9 Sep 2000 00:56:46 +1100, Fergus Henderson [EMAIL PROTECTED] pisze: If you define `p' as a syntactic function, e.g. then the monomorphism restriction does not apply, and so the type inferred for `p' will be the correct polymorphic type `Num a = a - a - a'. Also when an explicit type signature is given, it does not apply. Some people think that the monomorphism restriction should be removed. (There are no technical problems with this AFAIK.) I was under the impression that this introduced to increase efficency (prevents the same expression being multiply evaluated in certain circumstances) If this is the case then what about removing the restriction but issuing a warning if we compile code that would have caused the restriction to apply. -- __(" Marcin Kowalczyk * [EMAIL PROTECTED] http://qrczak.ids.net.pl/ \__/ ^^ SYGNATURA ZASTÊPCZA QRCZAK
RE: Patterns Catalog
-Original Message- From: Keith Wansbrough [mailto:[EMAIL PROTECTED]] Sent: 11 September 2000 15:07 To: Chris Angus Cc: 'Doug Ransom'; [EMAIL PROTECTED] Subject: Re: Patterns Catalog I've thought of this too. but I dont think there is anything out there which fits the bill. [I'd love someone to please correct me] [..] I think it would be a good thing to organise if anyone is willing to look ta this (If no-one is interested/ would rather do this) that person could be me as long as folk don't mind waiting a while for results. We started something like this on the Haskell Wiki, before it prematurely died. Has a certain historical authenticity to it, too, given that (IIRC) the eXtreme Programming / design patterns ideas started on a Wiki.. Was any of this preserved anywhere? Chris http://c2.com/cgi/wiki?ExtremeProgramming --KW 8-)
RE: student compiler in Haskell
I have used alex / happy a few times without too many problems I believe happy now contains yacc style information for operator precidence :-). If I were you I would use Happy + Alex for the scanner/parser. but use asdl for the definition of the data structures. (There is a link to this from the haskell.org tools page) I recently used all three on a similar translation project. It was initially written all in Haskell but there was a section which caused a bottleneck [An XML parser which had to read files 20Mb] which I was able to hand-craft in C lex/yacc and slot in using ASDL. Using ASDL meant that an escape-route was available when haskell proved to be too slow and also other folks (non haskellers) could write sections as long as the interface was defined. For the most part however haskell was fine and it was only the size of the files being read that crippled me really. Chris -Original Message- From: Dean Herington [mailto:[EMAIL PROTECTED]] Sent: 06 September 2000 04:26 To: [EMAIL PROTECTED] Subject: student compiler in Haskell I'm hoping to write the compiler for my graduate compilers course in Haskell, using Hugs on Windows NT. I find several choices for scanner and parser generators at http://www.haskell.org/libraries/. I would love to hear opinions about the overall suitability (usability, robustness, compliance with Haskell 98, etc.) of these tools (and any others that you consider useful) for such a project. Thanks in advance. Dean Herington Department of Computer Science University of North Carolina at Chapel Hill [EMAIL PROTECTED]
RE: code generation for other languages
For doinjg this sort of thing I have used asdl before which I find really useful. -Original Message- From: Manuel M. T. Chakravarty [mailto:[EMAIL PROTECTED]] Sent: 23 August 2000 14:09 To: [EMAIL PROTECTED] Cc: [EMAIL PROTECTED] Subject: Re: code generation for other languages Jeffrey Straszhiem [EMAIL PROTECTED] wrote, On Wed, Aug 23, 2000 at 12:26:38PM +1000, Timothy Docker wrote: I'm writing a haskell program that generates C++ code based upon some haskell data structures. At the moment, the code is somewhat ugly with lots of stuff like mutatorDef structName (name,vtype) = "inline void\n" ++ structName ++ "::" ++ (mutatorName name) ++ "( " ++ (cppParamType vtype) ++ " v ) {\n" ++ "" ++ (storageName name) ++ " = v;\n" ++ "}\n\n" All those ++ operators working on raw strings bug me, and manually getting the indentation correct is a pain. Is there a more functional approach to generating source code? I thought this could be a common enough task that there could be a library, but a perusal of haskell.org didn't seem to show anything relevant. To make matters worse, you're likely getting lousy efficiency with all of the ++ operators. Look through the code for showS in the Prelude for better ways to hook strings together. Paul Hudak talks about the efficient use of the show functions at: http://www.haskell.org/tutorial/stdclasses.html Now, with regard to the code being ugly, my suggestion would be to check out some of the pretty printer libraries out there, and to look through them. They basically solve a similar problem, except they first parse a normal program into a tree, then flatten the tree in a standard way. In your case you'll likely build the tree directly, then call the final stages of the pretty printer. There is no shortage of pretty printer libraries for Haskell, or for FP in general. The canonical approach is to define an internal data structure that represents C++ code, then let your mutator functions generate values of that data type (instead of strings), and finally pretty print values of this C++ data structure. That's cleaner and more flexible than the ++ cascades (or the show equivalent). Depending on how restricted and/or idiomatic the generate C++ code is, it makes sense to not have a data structure that can represent arbitrary C++ programs, but only a subset that is relevant for the code generation task at hand. So, you might want functions like mutatorDef :: ... - AbstractCPlusPlus prettyPrintACPP :: AbstractCPlusPlus - String Cheers, Manuel
RE:
-Original Message- From: Matthias Kilian [mailto:[EMAIL PROTECTED]] Sent: 06 August 2000 22:01 To: Mirko Pracht Cc: [EMAIL PROTECTED] Subject: Re: On Sun, 6 Aug 2000, Mirko Pracht wrote: average x | null x= 0.0 What does you make thinking the average of an empty list is 0? Its' obviously _|_, thus average xs = sum xs / length xs does this not need a "fromInt" to keep it happy I seem to remember a function genericLength once upon a type ... has this been removed nowadays? [which is inefficient, but simple] Kili -- _|_ is pronounced 'bottom', and is the greatest lower bound of a complete lattice. Nick Williams in comp.lang.functional
RE: Query
I would start by splitting the problem up tupleSum :: [Int]- (Int, Int) tupleSum xs = (neg, pos) where neg = ... SOME EXPRESSION INVOLVING xs ... pos = sum [ x | x - xs , x 0] -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] Sent: 03 August 2000 16:21 To: [EMAIL PROTECTED] Subject: Query Hi, Would mind asnswring the following : Write a Haskell function tupleSum of type tupleSum :: [Int]-- (Int, Int) that given a list of integers: @separetes all negatives from the list and then add -1 to each element of this sub-list; @sum all elements of the list of negatives and sum all elements of the list of positives and return these in a tuple Thanking you in advance for your assistance talk21 your FREE portable and private address on the net at http://www.talk21.com
RE: The type of zip
-Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] Sent: 25 July 2000 09:30 To: [EMAIL PROTECTED] Subject: Re: The type of zip Mon, 24 Jul 2000 09:04:58 +0100, Chris Angus [EMAIL PROTECTED] pisze: I dont agree. To me it seems simply like a logical extension of GHC/Hugs' Dynamic Type. We maybe couldnt get thye kind of reflection that (say) java has but we could get some useful stuff. eg. readDyn could have the signature String - Dynamic we can ask the Dynamic what type it is, request a function which does a job for that type and invoke the function we are now back in the world of static typing. around this area I'd be more interested in requesting values by name/type rather than discovering the type of an "untyped" object. i.e. rather than having a read / show method for each type we have a generic one which "asks" the type which type it actually is or requests a constructor by name. Ugh, IMHO it's bad. Such operations should be overridable for particular classes. It breaks abstract types. It throws away static check that a type can be shown. It forces to have runtime type information for all objects. It requires special cases for various primitive types like arrays. It's not compatible with current and future extensions to the language (like existential and universal quantification). I would generally avoid reflection in a statically typed language. -- __(" Marcin Kowalczyk * [EMAIL PROTECTED] http://qrczak.ids.net.pl/ \__/GCS/M d- s+:-- a23 C+++$ UL++$ P+++ L++$ E- ^^W++ N+++ o? K? w(---) O? M- V? PS-- PE++ Y? PGP+ t QRCZAK5? X- R tv-- b+++ DI D- G+ e h! r--%++ y-
RE: The type of zip
A little off-topic i know but ... Has anyone ever thought of trying to use reflection in these cases. i.e. still declare the instance but have a common method which examines the arguments and dynamiclly constructs the result depending (dynamically) on the type of the argument. I have never thought about using thius for zip but have for things like read / show. i.e. rather than having a read / show method for each type we have a generic one which "asks" the type which type it actually is or requests a constructor by name. -Original Message- From: Simon Peyton-Jones [mailto:[EMAIL PROTECTED]] Sent: 21 July 2000 17:29 To: 'Mark Tullsen'; Matt Harden Cc: [EMAIL PROTECTED] Subject: RE: The type of zip | No doubt. But seriously, I was thinking of a "built-in" Zippable | instance just like we have for Ord, Enum, Show, etc. | | That's what I thought you meant. But since I have a pet peeve about | how Haskell implementations work ... Is your peeve related to the built-in "deriving" mechanism? I agree!You might like to look at the paper Ralf Hinze and I have submitted to the Haskell Workshop http://research.microsoft.com/~simonpj/#derive It doesn't give a way to have a proper infinite family of tuples, but it does make generic programming easier. | I have a paper ("The Zip Calculus", MPC 2000) which is a bit more | ambitious, and is correspondingly more complex. My | solution allows | one to write the generic zip without use of the class system and | the theoretic need for an infinite number of instance | declarations. | It allows you to write transpose | transpose :: ((a,b),(c,d),(e,f)) - ((a,c,e),(b,d,f)) | generically for any m*n "matrix". | | I hope to write up a proposal for how to add this | capability to Haskell in the not too distant future. That certainly sounds interesting. Simon
RE: Haskell jobs (fwd)
Aren't most of these "java additions" MS J++ or MS specific rather than java/jdbc "run-anywhere" though? Hoping that this isnt the case Chris -Original Message- From: Frank Atanassow [mailto:[EMAIL PROTECTED]] Sent: 19 July 2000 10:22 To: S. Alexander Jacobson Cc: Manuel M. T. Chakravarty; [EMAIL PROTECTED] Subject: RE: Haskell jobs (fwd) S. Alexander Jacobson writes: Off the top of my head here are some Haskell specific things that we need: * HSP pages (like ASP or JSP or PHP) Erik Meijer has done this. Can't find the preprint online, though. (Erik?) * in memory Haskell server analogous to JServ that talks to apache mod_haskell? http://losser.st-lab.cs.uu.nl:8080/ * Haskell access to a pool of database connections Daan Leijen's HaskellDB? http://haskell.cs.yale.edu/haskellDB/ * Haskell access to Java classes Erik's Lambada http://www.cs.uu.nl/people/erik/Lambada.html * Encapsulation of Haskell as Java classe I don't know what that means, exactly. You mean a Hugs-like implementation in Java? Not a bad idea... do you need that, though, now that GHC can produce Java bytecode? Anyway, once the Java backend stabilizes, you would (in principle, at least :) be able to cross-compile GHC into a Java binary, and then use its upcoming interactive frontend. You still wouldn't have programmatic hooks (i.e., a Java-level rather than console-level interface) to the front-end, but it would become much easier to add. And all of this has to be relatively zipless and compatible with an existing JServ/JSP/Apache installation. Eh? "zipless"? -- Frank Atanassow, Dept. of Computer Science, Utrecht University Padualaan 14, PO Box 80.089, 3508 TB Utrecht, Netherlands Tel +31 (030) 253-1012, Fax +31 (030) 251-3791
RE: Showing tuples
Do you derive Show for MyData? -Original Message- From: Mike Jones [mailto:[EMAIL PROTECTED]] Sent: 09 May 2000 05:58 To: [EMAIL PROTECTED] Subject: Showing tuples Hi, I am having trouble with Show and tuples. I have a data structure, say: data MyData = ... And a value, say: value = (MyData..., MyData..., MyData) Then try to: show value I get a compiler message from ghc 4.05 that says: No instance for `Show (MyData, MyData, MyData)... What is the best way to deal with this problem? Thanks, Mike
RE: Showing tuples
Mike ... try this ...extend it to however long tuples you have data MyData = Foo | Bar deriving Show main = print (Foo,Foo,Foo,Foo,Foo,Foo) instance (Show tv1, Show tv2, Show tv3, Show tv4, Show tv5 , Show tv6) = Show (tv1,tv2,tv3,tv4, tv5,tv6) where showsPrec p (v1,v2,v3,v4,v5,v6) = showChar '(' . shows v1 . showChar ',' . shows v2 . showChar ',' . shows v3 . showChar ',' . shows v4 . showChar ',' . shows v5 . showChar ',' . shows v6 . showChar ')' instance (Read tv1, Read tv2, Read tv3, Read tv4, Read tv5 , Read tv6) = Read (tv1,tv2,tv3,tv4, tv5,tv6) where readsPrec p = readParen False (\s0 - [((v1,v2,v3,v4,v5,v6),s6A) | ("(",s1) - lex s0, (v1,s1A) - reads s1, (",",s2) - lex s1A, (v2,s2A) - reads s2, (",",s3) - lex s2A, (v3,s3A) - reads s3, (",",s4) - lex s3A, (v4,s4A) - reads s4, (",",s5) - lex s4A, (v5,s5A) - reads s5, (",",s6) - lex s5A, (v6,s6A) - reads s6, (")",s3) - lex s2A ]) -Original Message- From: Mike Jones [mailto:[EMAIL PROTECTED]] Sent: 09 May 2000 14:54 To: 'Chris Angus' Cc: [EMAIL PROTECTED] Subject: RE: Showing tuples Chris, Yes, I do derive Show for MyData. I was surprised it did not work. Mike -Original Message- From: Chris Angus [mailto:[EMAIL PROTECTED]] Sent: Tuesday, May 09, 2000 12:57 AM To: 'Mike Jones'; [EMAIL PROTECTED] Subject: RE: Showing tuples Do you derive Show for MyData? -Original Message- From: Mike Jones [mailto:[EMAIL PROTECTED]] Sent: 09 May 2000 05:58 To: [EMAIL PROTECTED] Subject: Showing tuples Hi, I am having trouble with Show and tuples. I have a data structure, say: data MyData = ... And a value, say: value = (MyData..., MyData..., MyData) Then try to: show value I get a compiler message from ghc 4.05 that says: No instance for `Show (MyData, MyData, MyData)... What is the best way to deal with this problem? Thanks, Mike
RE: doubly linked list
-Original Message- From: Peter Hancock [mailto:[EMAIL PROTECTED]] Sent: 28 April 2000 10:23 To: [EMAIL PROTECTED] Cc: [EMAIL PROTECTED] Subject: Re: doubly linked list "Jan" == Jan Kort [EMAIL PROTECTED] writes: Anyway, a doubly linked list could be defined like this: That was very interesting. It seems to generalise to put back-pointers and other context info in a variety of data structures. This seems a pretty performance-enhancing thing to do. It is reminiscent of Richard Bird's paper on cyclic structures. Peter I quite like the idea too but the thought of updating such a structure gives me a headache. Saying that ... this might encourage greater use of higher order fns rather than explicit recursion.
RE: doubly linked list
Would it not be better to tag a start point then we can manipulate this easier and move it back to a singly linked list etc. data Db a = Dd (Db a) a (Db a) | DStart (Db a) a (Db a) instance Show a = Show (Db a) where show xs = show (enumerate xs) instance Eq a = Eq (Db a) where xs == ys = enumerate xs == enumerate ys enumerate xs = enumerate' (rewind xs) enumerate' (DStart _ v r) = v : enumerate'' r enumerate' (Dd _ v r) = v : enumerate'' r enumerate'' (DStart _ v r) = [] enumerate'' (Dd _ v r) = v : enumerate'' r mapD f = dlink .(map f) .enumerate dlink ll = let (hd,lst)=dble' ll lst hd dble [x] prev foll = let h = Dd prev x foll in (h,h) dble (x:xq) prev foll = let h=Dd prev x nxt (nxt,lst) = dble xq h foll in (h,lst) dble' [x] prev foll = let h = DStart prev x foll in (h,h) dble' (x:xq) prev foll = let h=DStart prev x nxt (nxt,lst) = dble xq h foll in (h,lst) in hd left (Dd a _ _) = a left (DStart a _ _) = a right (Dd _ _ a) = a right (DStart _ _ a) = a val (Dd _ x _) = x val (DStart _ x _) = x rewind (Dd a _ _) = rewind a rewind a = a ffwd (Dd _ _ a) = ffwd a ffwd a = a -Original Message- From: Jerzy Karczmarczuk [mailto:[EMAIL PROTECTED]] Sent: 28 April 2000 11:12 Cc: [EMAIL PROTECTED] Subject: Re: doubly linked list Jan Brosius wrote: I wonder if it is possible to simulate a doubly linked list in Haskell. ... and the number of answers was impressive... Want some more? This is a short for *making* true double lists, and as an extra bonus it is circular. Slightly longer than the solution of Jan Kort, no empty lists. A data record with three fields, the central is the value, other are pointers. data Db a = Dd (Db a) a (Db a) deriving Show -- (don't try to derive Eq...) dlink constructs a circular list out of a standard list. Cannot be empty. The internal fct. dble is the main iterator, which constructs a dlist and links it at both ends to prev and foll. dlink ll = let (hd,lst)=dble ll lst hd dble [x] prev foll = let h = Dd prev x foll in (h,h) dble (x:xq) prev foll = let h=Dd prev x nxt (nxt,lst) = dble xq h foll in (h,lst) in hd You might add some navigation utilities, e.g. left (Dd a _ _) = a right (Dd _ _ a) = a val (Dd _ x _) = x etc. At least you don't need Monads nor Zippers. Keith Wansbrough proposes his article. I don't know it, when you find it please send me the references. But there are previous works, see the article published in Software 19(2), (1989) by Lloyd Allison, "Circular programs and self-referential structures". Jerzy Karczmarczuk Caen, France PS. Oh, I see now that the KW article has been found... Well, I send you my solution anyway.
RE: openfile :: String - String
You could try this: --OpenFile.hs module OpenFile where import IOExts openfile :: String - String openfile = unsafePerformIO . readFile -- end of file -Original Message- From: Hamilton Richards [mailto:[EMAIL PROTECTED]] Sent: 26 April 2000 14:04 To: [EMAIL PROTECTED] Subject: openfile :: String - String The Gofer prelude had a function openfile :: String - String which mapped file path names to strings containing the named files' contents. The Hugs98 Prelude doesn't seem to have anything like that function. Instead, it has things like readFile :: String - IO String Why would I want openfile instead of readFile? The problem in which the need for openfile arose is this: I want to load a binary search tree and a list with words read from a file, and then perform, interactively, several tests comparing the cost of searching the tree with that of searching the list. In addition to performing the tests interactively, I want to separate the cost of searching the list and the tree from the cost of constructing them. In order for the list and the tree to be used in several successive command-line evaluations without being reconstructed each time, they must be named globally. This is no problem with openfile, but readFile forces their names to be local to an IO command. Can anyone suggest a solution? Thanks, --Ham -- Hamilton Richards Jr.Department of Computer Sciences Senior Lecturer Mail Code C0500 512-471-9525 The University of Texas at Austin SHC 434 Austin, Texas 78712-1188 [EMAIL PROTECTED] --
Untrusted code
Hi, I was wondering if there was any way to run code which possibly threw an error in any version of Haskell. e.g. efficient3rdPartyAlgorithm :: Int - Int myOwnSlowAlgorithm :: Int - Int i.e. the idea is you run the efficent version and if falls over you run your own version. Cheers Chris
No Subject
Does anyone know where I can get some information on Lambada. I tried http://windows.st-lab.cs.uu.nl/Lambada/ but got a 403 (not authorised to view page) Cheers Chris
Java AST
Dear All, I am using Haskell (via ASDL) to write a translator (target language = java) and have designed an AST for Java. I want to be able to do fairly powerful source to source manipulations on this java tree and as such would value any constructive criticism of the way I have put together the data structrures. Sort of (..."Wouldn't it be easier to manipulate if you had represented X as "... sort of thing) Many thanks in advance Chris note for Haskellers x = FOO(x,x*,x?) | BAR = data X = FOO X [X] (Maybe X) | BAR x = (y) = type X = Y module Java { typeSpecifier = (typeName,dims?) typeName = PrimType(primitiveType) | QualType(qualifiedName) classNameList = (qualifiedName*) primitiveType = BOOLEAN | CHAR | BYTE | SHORT | INT | LONG | FLOAT | DOUBLE | VOID compilationUnit = (programFile) programFile = (packageStatement?,importStatements,typeDeclarations) packageStatement = PACKAGE(qualifiedName) typeDeclarations = (typeDeclaration*) importStatements = (importStatement*) importStatement = IMPORT (qualifiedName,star) boolean = JTrue | JFalse star = (boolean) ident = (string) qualifiedName = (ident*) typeDeclaration = (classHeader,fieldDeclarations) classHeader = (modifiers,classWord,ident,extends,interfaces) modifiers = (modifier*) final = (boolean) modifier = ABSTRACT | FINAL | PUBLIC | PROTECTED | PRIVATE | STATIC | TRANSIENT | VOLATILE | NATIVE | SYNCHRONIZED classWord = CLASS | INTERFACE interfaces = (classNameList) fieldDeclarations = (fieldDeclaration*) fieldDeclaration = FieldVariableDeclaration (fieldVariableDeclaration) | MethodDeclaration (methodDeclaration) | ConstructorDeclaration(constructorDeclaration) | StaticNonStaticInitializer(boolean,block) | TypeDeclaration (typeDeclaration) fieldVariableDeclaration = (modifiers,typeSpecifier,variableDeclarators) variableDeclarators = (variableDeclarator*) variableDeclarator = (declaratorName,variableInitializer?) variableInitializer = Expression(expression) | ArrayInitializers(arrayInitializers) arrayInitializers = (variableInitializer*) methodDeclaration = (modifiers,typeSpecifier,methodDeclarator,throws,methodBody) methodDeclarator = (declaratorName,parameterList,op_dim?) parameterList = (parameter*) parameter = (final,typeSpecifier,declaratorName) declaratorName = (ident,op_dim?) throws = (classNameList) methodBody = (block) constructorDeclaration = (modifiers,constructorDeclarator,throws,block) constructorDeclarator = (ident,parameterList) extends = (typeName*) block = (localVariableDeclarationsAndStatements) localVariableDeclarationsAndStatements = (localVariableDeclarationOrStatement*) localVariableDeclarationOrStatement = LocalVariableDeclaration( localVariableDeclaration) | Statement( statement) localVariableDeclaration = (final,typeSpecifier,variableDeclarators) statement = EmptyStatement | LabelStatement(labelStatement) | ExpressionStatement (expressionStatement) | SelectionStatement (selectionStatement) | IterationStatement (iterationStatement) | JumpStatement (jumpStatement) | GuardingStatement (guardingStatement) | Block (block) labelStatement = ID (ident ) | CASE (expression) | DEFAULT expressionStatement = (expression) selectionStatement = IF(expression,statement,statement?) | SWITCH (expression,block) iterationStatement = WHILE ( expression , statement ) | DO (statement, expression ) | FOR ( forInit?, forExpr?, forIncr?, statement) forInit = ExpressionStatements (expressionStatements) | LocalVariableDecl(localVariableDeclaration) forExpr = (expression) forIncr = (expressionStatements) expressionStatements = (expressionStatement*) jumpStatement = BREAK (ident?) | CONTINUE (ident?) | RETURN(expression?) | THROW (expression) guardingStatement = SYNCH ( expression,statement) | TRY (block,catches,finally?) catches = (catch*) catch = (catchHeader, block) catchHeader = CATCH ( typeSpecifier, ident? ) finally = ( block) primaryExpression = QualifiedName (qualifiedName) | SpecialName (specialName) | NewAllocationExpression (newAllocationExpression) |
RE: Job market
I am currently using Haskell at work although not to develop end - software We have a lot of legacy code which we want to convert to Java I am using a combination of happy , alex, asdlGen, hugs and GHC, writing in a monadic style. I tried to use Haxml but found it too inefficient for the size of files I needed to much so ended up using C - ASDL - Haskell and used the GHC extension libs. I found that by using haskell I managed to get a prototype system up and running in about 2 weeks which I dont think I could have done in another language. I wouldnt say that this was my normal programming language though as this tends to be more C++ / Java. Chris -Original Message- From: Michael Hobbs [mailto:[EMAIL PROTECTED]] Sent: 09 February 2000 16:49 To: [EMAIL PROTECTED] Cc: [EMAIL PROTECTED] Subject: Re: Job market [EMAIL PROTECTED] wrote: This is probably a stupid question, but... Are there any jobs out there to be had programming in haskell? My apologies if this is inapropriate for this list or if I missed it on the web site. Thanks- Brett I have never met an employer that has so much as even heard about Haskell. Due to the short supply of labor in the current (U.S.) job market, employers really can't afford to use anything other than commodity languages. (C, C++, Java, Visual Basic) That is, if your Haskell programmer up and leaves, good luck finding another one. I think the closest that you can reasonably expect is erlang over at Ericsson.
Relection
I posted this to comp.lang.functional a while ago but (apparently) no one had an opinion which I cant believe is the case :-) Chris I would be interested to know people's views on adding reflection to Haskell to get Factory-like behaviour. I was thinking that other modules could "export" values as being reflective and the compiled code could register these values at load-time into a list reflections :: [(FullyQualifiedName,Dynamic)] and values could be requested from it a la... lookup :: a - Name - Maybe a Where the initial "a" is needed to make it all typesafe If we had this we could implement additive code i.e. rather than myImageReader :: String - IO Image myImageReader name = case (getExtension name) of BMP - Bmp.readBmp name JMG - Jpg.readJpg name _ - error "unknown type" we could implement myImageReader :: String - IO Image myImageReader name = case (Reflect.lookup (bot::String - IO Image) (makeFnName name) of Just f - f name Nothing - error "unknown type" i.e. passing "myfile.bmp" to makeFnName gives "Bmp.readBmp" and passing "x.yz" to it gives "Yz.readYz" since the list of reflections is built at load time we can extend this functionality by simply linking extra modules with it i.e. main.o can read no file types main.o + bmp.o can read bitmaps main.o + bmp.o + jpg.o can read bmps and jpgs i.e. we do not have to exit case statements and extend types to add extra functionality in Bmp.hs say we could have module Bmp where import Image reflect readBmp readBmp :: String - IO Image ... which would get munged to module Bmp where import Image -- This gets appended to the global reflection list at load time -- [("Bmp.readBmp",toDynamic readBmp)] readBmp :: String - IO Image ... All of this means that the meaning of the code is not the following eval main userAndLibraryDefs but the following eval main (userAndLibraryDefs + LoadTimeDefs) and we still have ref. transparency
RE: Relection
By reflection I mean the sort of thing Java does in java.lang.reflect i.e. given the name/type of a function we can retrieve that function and subsequently use it in the same way that in java given the name of a class we can create instances of that class. i.e. it is quite common to have dialog which accepts a filename looks at the suffix turns that in to class name and picks up the class. That class knows how to deal with files of that type and all classes share a common interface. The sort of problem I'm describing is something I would try to use the Factoy design pattern for nin OO speak (GoF Design Patterns : Elements of Reusable Object-Oriented Software). In Haskell we have module Foo import Bmp ... ... Bmp.read filename i.e. we can only call the functions inside modules we have imported (in this case Foo can read bitmaps because it imports Bmp) However if we wanted to extend Foo's functionality so that it could read Gifs as well we would have to edit Foo module Foo import Bmp import Gif ... ... Bmp.read filename ... Gif.read filename etc and for each new format we wanted to add we would edit Foo.hs ... yeugh! if we had a mechanism for retrieving functions then this would not be necessary we could inspect the filename if it was a .gif then retrieve Gif.read if it was a .bmp then retrieve Bmp.read if it was a .foo then retrieve Foo.read etc now Foo's functionality may be extended in an additive rather than editive way module Foo import Reflect ...let fn = Reflect.getFn (bottom::String - ImageReader) name name = suffix+ ".read" suffix = getSuffix filename in case fn of Nothing - error ("Function that knows how to read " + suffix +" files does not exist") Just f - f filename -Original Message- From: Peter Hancock [mailto:[EMAIL PROTECTED]] Sent: 25 January 2000 11:13 To: Chris Angus Subject: Relection "Chris" == Chris Angus [EMAIL PROTECTED] writes: I posted this to comp.lang.functional a while ago but (apparently) no one had an opinion which I cant believe is the case :-) Hi Chris. The problem is likely to be that (like me) many people don't know what you mean by "reflection" -- I couldn't make it out from your message. [I know what reflection means in set theory, but (pardon my ignorance) I haven't heard of it in FP.] Maybe you could post a URL for a paper which explains this concept well? Regards, Peter
RE: Singletons and Reflection
Ok ... this is a lot neater than what I had in mind but what about the reflective part? -Original Message- From: Daan Leijen [mailto:[EMAIL PROTECTED]] Sent: 15 December 1999 10:49 To: 'Chris Angus'; [EMAIL PROTECTED] Subject: RE: Singletons and Reflection What do folk out there think to the idea of having a std module in Haskell which contains dynamic environment info. things I mean are progName :: String args:: String Representing the 'args' as a value in haskell is probably not the right thing to do. For one thing, it is not possible to substitute the value 'args' with its definition, since it is unknown until load time. I think that the 'dynamic environment' info is much better represented with implicit arguments. (already implemented by Jeffrey Lewis in the november hugs release). (Implicit Parameters: Dynamic Scoping with Static Types. Jeffrey Lewis, Mark Shields, Erik Meijer, John Launchbury: http://www.cse.ogi.edu/~mbs/pub/implicit.ps.gz ) The type of main would than be: main :: (?arguments, ?environment) = IO () And we could use these arguments anywhere in the haskell program (without making everything part of the IO monad) numArgs :: (?arguments) = Int numArgs = length (?arguments) Actually, the H/Direct compiler uses an unsafePerformIO to avoid having to pass around options through all the compiler. Implicit arguments would help here too. All the best, Daan.
Singletons and Reflection
Hi, What do folk out there think to the idea of having a std module in Haskell which contains dynamic environment info. things I mean are progName :: String args:: String and maybe funs like getProperties :: FileName - PropertyLookup (obviously this getProperties fn whould have to memoise the file contents to preserve referential transparency). This would be an alternative to definitions like installationRoot = "/usr/local/" instead we could write installationRoot = lookup "IROOT" Globals.env Also I was thinking that other modules could "export" values as being reflective and the compiled code could register these values at load-time into a list reflections :: [(FullyQualifiedName,Dynamic)] and values could be requested from it a la... lookup :: a - Name - Maybe a Where the initial "a" is needed to make it all typesafe If we had this we could implement additive code i.e. rather than myImageReader :: String - IO Image myImageReader name = case (getExtension name) of BMP - Bmp.readBmp name JMG - Jpg.readJpg name _ - error "unknown type" we could implement myImageReader :: String - IO Image myImageReader name = case (Reflect.lookup (bot::String - IO Image) (makeFnName name) Just f - f name Nothing - error "unknown type" i.e. passing "myfile.bmp" to makeFnName gives "Bmp.readBmp" and passing "x.yz" to it gives "Yz.readYz" since the list of reflections is built at load time we can extend this functionality by simply linking extra modules with it i.e. main.o can read no file types main.o + bmp.o can read bitmaps main.o + bmp.o + jpg.o can read bmps and jpgs i.e. we do not have to exit case statements and extend types to add extra functionality in Bmp.hs say we could have module Bmp where import Image reflect readBmp readBmp :: String - IO Image ... which would get munged to module Bmp where import Image -- This gets appended to the global reflection list at load time -- [("Bmp.readBmp",toDynamic readBmp)] readBmp :: String - IO Image ... All of this means that the meaning of the code is not the following eval main userAndLibraryDefs but the following eval main (userAndLibraryDefs + LoadTimeDefs) and we still have ref. transparency Comments / Flames ? Chris
RE: Still confused
Hi all. Steve Frampton [EMAIL PROTECTED] wrote: foo x = ['1'] ++ foo(x div 10) *** term : foo *** type : ((a - a - a) - b - Int) - [Char] *** does not match : Int - [Char] Can someone please explain how to decipher the type line in this error message in such a way that we come to div being used incorrectly? I'm afraid that my mind doesn't immediately jump to the conclusion that div without quotes is not an infix operator when I see the error message. Surely minor syntactical errors can be reported in a more meaningful manner? The whole problem is that is is not a syntax error. The syntax is valid. It's a tying error. Admitedly a confusing one. Cheers Mike Thomas.
RE: Haskel Type Question
I'm guessing that the problem is that fos -0.5 [1,1,1,1] is being parsed as ((fos) - (0.5)) [1,1,1,1] so that the 0.5 implies an instance of class Fractional which implies by the type of (-) (-) :: Num a = a - a - a that fos is also an instance of class Fractional But since it isnt we get an error if you do a fos (-0.5) [1,1,1,1] this is parsed as fos (negate 0.5) [1,1,1,1] ... etc This is the reason I prefer the notation negate x = ~x and subtract x y = x - y which means that (-x) is a section and (~x) is a negation As I say I am not completely sure this is the 'exact' reason since I thought that the above example would parse as (fos) - (0.5 [1,1,1,1]) Clearly garbage! it will however certainly be along these lines. Hope this helps Chris -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]]On Behalf Of Matthew Donadio Sent: Monday, November 09, 1998 2:02 PM To: Haskell List Subject: Haskel Type Question I have two functions fos:: Num a - [a] - [a] fos a x = fos' a 0 x fos':: Num a - a - [a] - [a] fos' _ _ [] = [] fos' a y1 (x:xs) = y : fos' a y xs where y = a * y1 + x Why does fos -0.5 [ 1, 1, 1, 1 ] give me [a] - b - [b] - [b] is not an instance of class "Fractional" while fos (-0.5) [ 1, 1, 1, 1 ] evaluates just fine? I'm using Hugs 1.4. Thanks. -- Matt Donadio ([EMAIL PROTECTED]) | 43 Leopard Rd, Suite 102 Sr. Software Engineer | Paoli, PA 19301-1552 Image Signal Processing, Inc. | Phone: +1 610 407 4391 http://www.isptechinc.com | FAX: +1 610 407 4405