Re: [Haskell-cafe] ANNOUNCE: vector 0.1 (efficient arrays with lots of fusion)
On Sun, Jul 13, 2008 at 12:31 AM, Roman Leshchinskiy [EMAIL PROTECTED] wrote: Hi all, the vector library will eventually provide fast, Int-indexed arrays with a powerful fusion framework. It's very immature at the moment (I haven't tested most of the code) and implements just a few combinators but I thought releasing early wouldn't hurt. Use at your own risk and expect things to break horribly! Sounds interesting. How does this compare to the uvector library? Thanks, Levi ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] (Lazy) SmallCheck and peano numbers
Hi, I have the following definitions type Zero type Succ a so that I can muck around with a Vector type that includes its length encoded in its type. I was wondering whether it was possible to use SmallCheck (or QuickCheck) to generate random Peano numbers? Is there an issue here in that what I actually want to generate is a type rather than a value? I do have reifyInt :: Int - (forall a. ReflectNum a = a - b) - b but, I'm not sure if this can help me when I need to generate other values based upon that type (e.g., two vectors with the same size type) Thanks, Levi ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: (Lazy) SmallCheck and peano numbers
If so, you could write a SmallCheck Series instance as follows. instance Serial (Vec Zero a) where series = cons0 nil instance (Serial a, Serial (Vec n a)) = Serial (Vec (Succ n) a) where series = cons2 (|) If we have the property prop_vector :: Vec (Succ (Succ Zero)) Bool - Bool prop_vector (V xs) = xs == xs we can check it, and only 2 element vectors will be tested I have some code up now at http://hpaste.org/8420 It looks pretty much like what you've written above and is what I am doing for the moment, but for various size vectors from zero to four. Now, it seems what you really want to do is define polymorphic properties like prop_poly :: Vec n Bool - Vec n Bool - Bool and have SmallCheck check all equal-sized vectors. If so, good question! :-) Yep, this would be exactly what I'm after. Thanks for a better write up and background on what I'm after than I gave :) I'm thinking the property might be written as prop_poly:: size - Vec size Bool - Vec size Bool - Bool, so that the size is generated randomly and the types take care of ensuring the vectors generated are of the same size. Levi ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: (Lazy) SmallCheck and peano numbers
On Fri, Jun 20, 2008 at 3:30 AM, Benedikt Huber [EMAIL PROTECTED] wrote: Levi Stephen schrieb: Hi, I have the following definitions type Zero type Succ a so that I can muck around with a Vector type that includes its length encoded in its type. I was wondering whether it was possible to use SmallCheck (or QuickCheck) to generate random Peano numbers? Is there an issue here in that what I actually want to generate is a type rather than a value? I do have reifyInt :: Int - (forall a. ReflectNum a = a - b) - b but, I'm not sure if this can help me when I need to generate other values based upon that type (e.g., two vectors with the same size type) Hi Levi, For QuickCheck, I know it is possible as long as you do not need to use type level functions in your tests. For example, using Alfonso's type-level and parametrized-data packages, one can write: instance (Nat n, Arbitrary a) = Arbitrary (FSVec n a) where arbitrary = liftM (unsafeVector (undefined :: n)) $ mapM (const arbitrary) [1..toInt (undefined :: n)] propLength :: forall n a. (Nat n) = FSVec n Integer - Bool propLength (FSVec xs) = P.length xs == toInt (undefined :: n) propLengthEqual :: forall n a. (Nat n) = FSVec n Integer - FSVec n Integer - Bool propLengthEqual v1 v2 = length v1 == length v2 tests1 = forM_ [0..100] $ \n - reifyIntegral n $ \(t :: ty) - quickCheck (propLength :: FSVec ty Integer - Bool) tests2 = forM_ [0..100] $ \n - reifyIntegral n $ \(t :: ty) - quickCheck (uncurry propLengthEqual :: (FSVec ty Integer,FSVec ty Integer) - Bool) Thanks for the example code. Ideally it would be great to have n generated also. Any thoughts on whether something like propLengthEqual :: forall n a. (Nat n) = n - FSVec n Integer - FSVec n Integer - Bool propLengthEqual _ v1 v 2 = length v1 == length v2 with an arbitrary instance for generate all Nat n's is possible? Is something like instance (forall n. Nat n) = Arbitrary n possible/legal haskell? and would it for the above test? best regards, benedikt Thanks, Levi ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] hmp3 compilation problem
Hi, I am trying to compile hmp3. I have the version from darcs at http://code.haskell.org/~dons/code/hmp3 I am getting the following errors: Tree.hs:190:14: No instance for (Binary FilePathP) arising from a use of `get' at Tree.hs:190:14-16 Possible fix: add an instance declaration for (Binary FilePathP) In a 'do' expression: nm - get In the expression: do nm - get i - get return (File nm i) In the definition of `get': get = do nm - get i - get return (File nm i) Tree.hs:236:31: Couldn't match expected type `L.ByteString' against inferred type `bytestring-0.9.0.1:Data.ByteString.Lazy.Internal.ByteString' In the second argument of `L.writeFile', namely `(compress (encode s))' In the expression: L.writeFile f (compress (encode s)) In the definition of `writeTree': writeTree f s = L.writeFile f (compress (encode s)) Tree.hs:240:46: Couldn't match expected type `bytestring-0.9.0.1:Data.ByteString.Lazy.Internal.ByteString' against inferred type `L.ByteString' In the first argument of `decompress', namely `s' In the first argument of `decode', namely `(decompress s)' In the first argument of `return', namely `(decode (decompress s))' Any help is much appreciated. Thanks, Levi ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] First go at reactive programming
Hi, Below is a version that was aimed at getting rid of the (Handle,IO (Request a)) tuples and as a result made it easier to remove the IO monad from some types, but I don't think it removed it completely from any methods. module Main where import Control.Applicative import Control.Concurrent import Control.Monad import Data.Reactive import Network.BSD import Network.HTTP import Network import System.IO import Text.XHtml.Strict type RequestHandler = Request - Response main = runHttpServer helloWorldHandler helloWorldHandler :: RequestHandler helloWorldHandler = Response (2,0,0) [] . prettyHtml . helloWorldDoc helloWorldDoc :: Request - Html helloWorldDoc rq = header thetitle Hello World +++ body(h1 Hello World +++ p show rq) runHttpServer :: RequestHandler - IO a runHttpServer r = socketServer = runE . fmap (handleConnection r) socketServer :: IO (Event Handle) socketServer = withSocketsDo $ do (e,snk) - mkEventShow Server sock- listenOn (PortNumber 8080) forkIO $ forever $ acceptConnection sock $ snk return e handleConnection :: Handle - RequestHandler - IO () handleConnection h r = handleToRequest h = responseSend h . runRequestHandler r handleToRequest :: Handle - IO (Result Request) handleToRequest = receiveHTTP runRequestHandler :: RequestHandler - Result Request - Result Response runRequestHandler r rq = rq `bindE` (Right . r) responseSend :: Handle - Result Response - IO () responseSend h rsp = either print (respondHTTP h) rsp close h acceptConnection :: Socket - (Handle - IO ()) - IO ThreadId acceptConnection s k = accept s = \(h,_,_) - forkIO $ k h instance Stream Handle where readLine h = hGetLine h = \l - return $ Right $ l ++ \n readBlock h n = replicateM n (hGetChar h) = return . Right writeBlock h s = mapM_ (hPutChar h) s = return . Right close = hClose ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] First go at reactive programming
Hi, Listed below is my first experiment with reactive programming. It is a simple web server written using the Data.Reactive[1] library. The intended interface is given by the runHttpServer function, so the remainder is intended to be internal. I'd be happy to hear comments on any parts of this, but am particularly interested in the following: 1. Is this kind of code what is intended from reactive programming? 2a. I'm not sure about passing the (Handle,...) tuple around. Is there a way to avoid this? 2b. I'm not sure of the best place to handle possible socket exceptions 2c. I'd like to be able to pass a function of type Event Request - Event Response to runHttpServer, so that reactive programming could be used throughout client code also, but the (Handle,...) tuples seem to be getting in the way. 3. I have a feeling there's a clearer way to write responseSend. Thanks, Levi [1] http://www.haskell.org/haskellwiki/Reactive module Main where import Control.Applicative import Control.Arrow ((),()) import Control.Concurrent import Control.Monad import Data.Reactive import Network.BSD import Network.HTTP import Network import System.IO import Text.XHtml.Strict type RequestHandler = Request - Response main = runHttpServer helloWorldHandler helloWorldHandler :: RequestHandler helloWorldHandler _ = Response (2,0,0) [] $ prettyHtml helloWorldDoc helloWorldDoc = header thetitle Hello World +++ body h1 Hello World runHttpServer r = socketServer = runE . handleConnection r socketServer :: IO (Event Handle) socketServer = withSocketsDo $ do (e,snk) - mkEventShow Server sock - listenOn (PortNumber 8080) forkIO $ forever $ acceptConnection sock $ snk return e handleConnection :: RequestHandler - Event Handle - Event (IO ()) handleConnection r = handleToRequest runRequestHandler r responseSend handleToRequest :: Event Handle - Event (Handle, IO (Result Request)) handleToRequest e = fmap (id receiveHTTP) e responseSend :: Event (Handle, IO (Result Response)) - Event (IO ()) responseSend e = fmap (\(h,rsp) - rsp = either (putStrLn . show) (respondHTTP h) close h) e runRequestHandler :: RequestHandler - Event (Handle, IO (Result Request)) - Event (Handle, IO (Result Response)) runRequestHandler r e = fmap hrToHr e where rqhdl :: Result Request - Result Response rqhdl rq = bindE rq (Right . r) hrToHr :: (Handle, IO (Result Request)) - (Handle, IO (Result Response)) hrToHr (h,req) = (h, liftA rqhdl req) acceptConnection s k = accept s = \(h,_,_) - forkIO $ k h instance Stream Handle where readLine h = hGetLine h = \l - return $ Right $ l ++ \n readBlock h n = replicateM n (hGetChar h) = return . Right writeBlock h s = mapM_ (hPutChar h) s = return . Right close = hClose ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] FP design
Bulat Ziganshin wrote: Hello Andrew, Tuesday, November 6, 2007, 10:55:58 PM, you wrote: for me, abstraction is anything that i want to be an abstraction. i just write code in the close-to-natural language and it becomes Haskell program when appropriate syntax applied. Well, in my experience, figuring out just the right abstractions to use i don't think about abstractions, just using top-down approach. for me, FP benefit is that when you see that some two things are similar - you can factor out this similarity. in OOP, you should translate it into some class interface, in Haskell you just define parameterized code/data and it works. selection of good abstractions based on these two criteria: 1) factoring out common parts and 2) existence of natural description of the factored part. if i don't see natural description, i can slightly change the factored part This thread sums up some of my thoughts pretty well. I'm coming from OOP where I was getting comfortable and was confident of spotting appropriate abstractions. Now I have to learn how to select the appropriate abstractions in Haskell. e.g., selecting between a variant type or type class is often a tricky one for me. It is good to hear that people are having success with the code, refactor duplication, repeat process. I have used this in OOP as well and the path it takes is interesting to compare with initial design thoughts. Again, it's just choosing the best way to remove this duplication :) Levi ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] FP design
Donn Cave wrote: But in the specific matter I'm wrestling with, the Java library's OOP model is, to its credit, allowing me to do some things. I'm using their standard LDAP client library, but swapping in my own function to read X509 certificates for the SSL. Actually, swapping in my own SSL socket implementation, which in my case just calls the standard library SSL socket implementation to do most of the work. Now it's not like I can't imagine it working better - it may be a little fragile, for one thing - but I have wondered what facilities a Haskell design could have drawn on to de-couple implementation components like that. Let's say you download an IMAP mail client library, and look to see if it can operate on a UNIX pipe; on an SSL socket; authenticate with GSSAPI Kerberos 5 -- when none of those things are supported out of the box. (As I have needed, and done, all three of those with the standard Python IMAP library module.) You may also want its I/O operations to integrate with some dispatching core, for a GUI. But of course you also want the basic interface to be simple in this area - the IMAP protocol itself is complicated enough! I have similar questions about Haskell abstracting away implementations behind interfaces as well. I have become used to an approach where I will not worry about databases/persistence when beginning. I will create an interface to a database layer (e.g., save(object), retrieve(id), findByName(name)) etc., and an implementation that uses in memory collections to begin with. Later I will replace this with database calls. This also helps in my current project as we support multiple databases. If findByName requires different SQL on different databases it's easy to have a different implementation used at run time. How does this type of approach work in Haskell? or what is the Haskell way to achieve this? Levi ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] FP design
Tim Docker wrote: levi.stephen wrote: My concern (which may be inexperience ;) ) is with the monads here though. What if I hadn't seen that the IO monad (or any other Monad) was going to be necessary in the type signatures? You'd have some refactoring to do :-) But actually, it's not possible to create an interface that works this way without using some monad, as the interface relies on side-effects. A pure interface would have to look something like: I agree in this case the monad use is clear. Practically it might a case of if a monad is needed, it's either obvious, or its introduction indicates a refactor being a good thing and will lead to a better design. Levi ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] FP design
Tim Docker wrote: levi.stephen wrote: I have similar questions about Haskell abstracting away implementations behind interfaces as well. I have become used to an approach where I will not worry about databases/persistence when beginning. I will create an interface to a database layer (e.g., save(object), retrieve(id), findByName(name)) etc., and an implementation that uses in memory collections to begin with. Later I will replace this with database calls. How does this type of approach work in Haskell? or what is the Haskell way to achieve this? If OO is a good approach for a problem, it's straightforward to model it in haskell. If you plan to access an external DB in any case, then the interface will involve the IO Monad. Something along the lines of: data Object data ID data ObjectStore = ObjectStore { save :: Object - IO ID, retrieve :: IO - IO (Maybe Object), retrieveByName :: String - IO (Maybe Object) } createMemoryStore :: IO ObjectStore connnectExternalStore :: ConnectionParams - IO ObjectStore Tim Thanks for the example. I keep forgetting that I can have use functions like this. I keep having data types made up of just values and/or type classes. I should probably use types like the above more often. My concern (which may be inexperience ;) ) is with the monads here though. What if I hadn't seen that the IO monad (or any other Monad) was going to be necessary in the type signatures? Levi ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] FP design
Hi, I'm was wondering how most people work during when designing a functional program. Do you create data structures/types first? Do you work from some type signatures? For example, take a blog. Is the first step likely to be something like: data BlogEntry = BlogEntry { title::String,content::String,comments::[Comment] } type Blog = [BlogEntry] or more likely thinking about what functions will be required: addEntry :: BlogEntry - Blog - Blog displayBlog :: Blog - HTML displayEntry :: BlogEntry - HTML I'm trying to get my brain out of thinking OO thinking more functionally. Thanks, Levi lstephen.wordpress.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Help understanding type error
Hi, I'm after some help understanding either what I'm doing wrong, or why this error occurs. I have a data type: data T a = forall b. (Show b) = T b a and I want to use/extract 'b' from this. extShow (T b _) = b This gives the following compilation error: extest.hs:5:0: Inferred type is less polymorphic than expected Quantified type variable `b' escapes When checking an existential match that binds $dShow :: {Show b} b :: b The pattern(s) have type(s): T t The body has type: b In the definition of `extShow': extShow (T b _) = b I tried adding a type signature: extShow' :: (Show b) = T a - b extShow' (T b _) = b Now I get a different error: extest.hs:8:19: Couldn't match expected type `b' (a rigid variable) against inferred type `b1' (a rigid variable) `b' is bound by the type signature for `extShow'' at extest.hs:7:18 `b1' is bound by the pattern for `T' at extest.hs:8:10-14 In the expression: b In the definition of `extShow'': extShow' (T b _) = b It seems (to newbie me ;) ) like it should be possible to extract the first part of T, and deduce that it is an instance of the class 'Show'. The following seems ok: doShow (T b _) = putStrLn (show b) Thanks, Levi ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Help understanding a partial application
Hi, I was browsing through the source code for Data.Foldable and having trouble comprehending it (which was kind of the point of browsing the code, so I could learn something ;) ) I'm looking at foldl foldl :: (c - d - c) - c - t d - c foldl f z t = appEndo (getDual (foldMap (Dual . Endo . flip f) t)) z But, I haven't got very far. I'm still trying to follow: Endo . flip f f is of type c-d-c, so this makes flip f of type d-c-c. I think the Endo constructor is of type (a-a)-Endo a I think a is binding to a function type here, but can not work out what. (From memory) ghci reports :t Endo . flip (+) Num a = a - Endo a So, this looks like a partial application of the constructor? But, this still isn't helping me understand. Any thoughts or pointers that might help me comprehend what's happening? Thanks, Levi lstephen.wordpress.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Help understanding a partial application
Ryan Ingram wrote: Just expand out the function composition: Dual . Endo . flip f = (\x - Dual (Endo (flip f x))) which has the type d - Dual (Endo c). -- ryan Aha. I didn't get this straight away, but once I looked at the type signature for function composition, it became clear. Thanks, Levi ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: I'm stuck in my thought experiment
If I wanted to develop the widgets themselves separately from the layout, I would probably do something like this: class Widget a where render :: a - Html bbox :: a - Size type Layout = forall a. Widget a = Widget a | Rows Spacing [Layout] | Columns Spacing [Layout] | Grid Spacing [[Layout]] type Page = Page String Layout renderLayout :: Layout - Html renderPage :: Page - Html I'm unsure this gives what I'm after. I'm trying to have layouts consist of Widgets (e.g., header images, common menu), and as pages also consist of Widgets it seems like they can be modelled using a common type/construct. Well if you want to abstract over the layout too, you can just add instance Widget Layout where render = renderLayout bbox = ... But just because you can, doesn't mean you should. I don't know the full details of your design, but what do you gain by allowing the layout to intermingle with the widgets? Is worth the extra complexity? If you treat layout as just another widget then it becomes harder to answer specific questions about the page layout because you have less information in your tree. Layout might not actually be the right term. Page template might be better. What I'm trying to gain is best described with an example. * I have a template with a header image, and footer text. * I create another template defined as the previous, but with a menu bar down the left. * I create a page based on the previous with some text. The gain comes from when I want to change the header image, or add a Login/Register box on all pages, I only edit the first template. Levi ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: I'm stuck in my thought experiment
Al Falloon wrote: Maybe I am misunderstanding your requirements, but it seems to me that the simplest solution would be best in this case: data Widget = BlogWidget [Article] | TextWidget String | MenuWiget Menu | Rows Spacing [Widget] | Columns Spacing [Widget] You can also add a type parameter if you want to be able to carry around extra metadata about pages, or you could even parameterize the Article and Menu types if you want to be able to extend them separately or if you want to ensure your layout algorithms don't depend on widget contents by keeping their type abstract. Thanks for pointing out a simple solution. Over thinking this is something I'm worried about :) This code seems to indicate that you want to be able to extend the widget types without changing this source file. This is a good goal, but it may not be worth the extra complexity. Ideally, I'd like Widgets to be added through hs-plugins or similar. That is a ideal goal though, not a necessity. Also, this looks a lot like the Composite pattern from OO. A rule of thumb that I use is: if I would do this with inheritance in OO, I probably want a variant in FP. Since Composite depends on the inheritance of the composite object type, I would probably look to use a single data type with multiple constructors for the different compisites like the Widget type above. Interesting. I've been curious how OO concepts can map to FP, as most specs (consider stuff like DOM) seem to be written with OO implementaitons in mind. If I wanted to develop the widgets themselves separately from the layout, I would probably do something like this: class Widget a where render :: a - Html bbox :: a - Size type Layout = forall a. Widget a = Widget a | Rows Spacing [Layout] | Columns Spacing [Layout] | Grid Spacing [[Layout]] type Page = Page String Layout renderLayout :: Layout - Html renderPage :: Page - Html I'm unsure this gives what I'm after. I'm trying to have layouts consist of Widgets (e.g., header images, common menu), and as pages also consist of Widgets it seems like they can be modelled using a common type/construct. The issue becomes, given a parent page and the customized content for the child page, what is the best way to insert the customized content at the right point? Might a tree like structure be useful? But, how do you work out where in the tree child content gets added? Store a traversal with each sub tree of child page content that basically says 'insert here'? This is probably a good use for a zipper (a kind of functional iterator). http://en.wikibooks.org/wiki/Haskell/Zippers that way you can pass around a value that means right here, and its clear where the substitution will happen. I was wondering with zippers were appropriate, or if I just had them in mind becuase I'd read so much about them lately :) So you want some sort of wildcard element that can be substituted in later? Maybe I am misunderstanding your requirement, but if thats the behavior you want, you should check out the term-level evaluators for lambda calculus for inspiration on substitution, but I expect your requirement may be simpler than that. I'm thinking a BlankWidget or ReplacableWidget is a fairly simple option. They could be named for the case of multiple replacements, and have a method similar to -- src - replacements- result replaceWidgets :: Widget - [(String,Widget)] - Widget which replaces all ReplacableWidgets in the source Widget with those specified. Would you happen to have some links on the evaluators for lambda calculus you talk about? I'm not as familiar as I should be with lambda calculus It might be simple to have a PlaceHolderWidget. Then insertions of the child page content happens at each of those widgets. This just gets trickier if I start considering multiple extension points for child pages and what happens when the layout/parent page changes. This is why I'm thinking I may be going along a bad path here. Exactly. With multiple substitutions you get into issues of naming, so thats why looking at lambda calculus evaluators would be the right inspiration, but I think it may be more complicated than you need. The zipper approach might be easier. I think I will try and investigate both approaches. I'm after the process here, rather than the end result Thanks Levi lstephen.wordpress.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] I'm stuck in my thought experiment
Hi, Apologies for a long post that may not be totally clear. I was thinking through a problem and how the data might be represented in Haskell. I'm now stuck and frustrated. Now, I'm not even sure whether I'm on the right track (I might still be thinking too OO). Suggestions/ideas would be much appreciated. I was imagining a drag and drop web page designer. There are a bunch of Widgets (e.g., BlogWidget, TextWidget, MenuWidget, etc) that the user can place on the page. Along with these are layout/container widgets (e.g., ColumnLayoutWidget) that can contain other widgets. I'm looking at a data structure that would allow this to be represented in Haskell, so I'm keeping in mind that these won't be written in code, but generated on the fly somehow (e.g., from a database or file). So, my thoughts were along the lines of something like: class Widget a where render :: a - Html -- A page has a title and a Widget. -- I know this isn't valid Haskell, but I'm not sure how to specify what I -- want here. (existential types?) data Page = Page String Widget data TextWidget = TextWidget String instance Widget TextWidget -- An example layout widget data ColumnLayoutWidget = ColumnLayoutWidget [Widget] instance Widget ColumnLayoutWidget ... etc... So, entire pages might be represented something like: Page Main (ColumnLayoutWidget [MenuWidget, TextWidget mainPageText]) Page About (ColumnLayoutWidget [MenuWidget, TextWidget aboutPageText]) Where I get stuck, is I want to extract layout information into a parent page. This would allow global changes such as adding a header image to the above pages to be done once only. So I want to be able to have something like: layout = Page Main (ColumnLayoutWidget [MenuWidget, ??? ]) mainPage = ChildPage layout [TextWidget mainPageText] aboutPage = ChildPage layout [TextWidget aboutPageText] So, each page is it's layout/parent page, with additional widgets inserted/added. The issue becomes, given a parent page and the customized content for the child page, what is the best way to insert the customized content at the right point? Might a tree like structure be useful? But, how do you work out where in the tree child content gets added? Store a traversal with each sub tree of child page content that basically says 'insert here'? It might be simple to have a PlaceHolderWidget. Then insertions of the child page content happens at each of those widgets. This just gets trickier if I start considering multiple extension points for child pages and what happens when the layout/parent page changes. This is why I'm thinking I may be going along a bad path here. Thanks, Levi lstephen.wordpress.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Avoiding boilerplate retrieving GetOpt cmd line args
Hi, Not sure if this will help avoid the boilerplate, but I've always liked the approach at http://leiffrenzel.de/papers/commandline-options-in-haskell.html (particularly the section Towards a higher level) for being able to specify defaults. It's the best resource I've found on command line options in Haskell so far. Levi Ok, I'm writing a command line tool, using System.Console.GetOpt to handle command line arguments. My Flags structure so far is data Flag = Filter String | DateFormat String | DocStart String | DocEnd String ... and I want to write accessor functions that return the strings if specified, otherwise returning a default. The best I've been able to do is this: getFilter = getString f Markdown.pl where f (Filter s) = Just s f _ = Nothing getDateFormat = getString f %B %e, %Y where f (DateFormat s) = Just s f _ = Nothing getDocStart = getString f ^{-$ where f (DocStart s) = Just s f _ = Nothing getDocEnd = getString f ^-}$ where f (DocEnd s) = Just s f _ = Nothing using a generic accessor function `getString`. There are eight (and growing) needless lines here, where what I really want to do is to pass the constructors `Filter`, `DateFormat`, `DocStart`, or `DocEnd` to the function `getString`. ghci types each of these as `String - Flag`, so one at least knows how to type such a `getString`, but using a constructor-passed-as-an-argument in a pattern match is of course a Parse error in pattern. (I expected as much, but I had to try... `String - Flag` is not enough information to make it clear we're passing a constructor, rather than some hairy arbitrary function, so such a pattern match would be undecidable in general.) So what's the right idiom for avoiding this boilerplate? Thanks, Dave ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Parsec question
Hi, Fairly new to Haskell and trying some parsec. (Also, new to parsers/interpreters) I had come up with this, which works, but I can't help thinking there's a better way :) | newtype Identifier = Identifier String newtype Literal = StringLiteral String -- to be extended later data Primary = PrimaryLiteral Literal | PrimaryIdentifier Identifier || primary = do { i - identifier; return $ PrimaryIdentifier i; } | do { l - stringLiteral; return $ PrimaryLiteral l; } || identifier = do i - many1 letter return $ Identifier i stringLiteral = do (char '\'') s - manyTill anyChar (char '\'') return $ StringLiteral s Is there a way through combining types/parsers that the double do block in primary could be avoided? I understand it's necessary right now because the parsers identifier and stringLiteral return different types, so I can't just write: i - identifier | stringLiteral So, I'm not sure whether my types need work, the parsers, or if this is the simplest way. Thanks, Levi lstephen.wordpress.com PS, have lurked on the list for a while, enjoy the discussions and content. | ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Parsec question
Tillmann Rendel wrote: My self-defined monadic combinator of choice to use with parsec is a ~ b = a = \x - b return x It works like (), but returns the result of the first instead of the result of the second computation. It is kind of an alternative for between: between lparen rparen p == lparen p ~ rparen Cool. I've always liked how Parsec made parsers so readable, and this makes it even more so. It can be usefull like this: data Term = TVar Identifier | TTerm Identifier [Term] term = (return TTerm `ap` try (identififer ~ lparen) `ap` (term `sepBy` comma ~ rparen)) | (return TVar `ap` identifier) After accepting lparen, the second branch is discarded. Interesting. I think I'll have to keep this one around. Not sure if I'll need it, but its the kind of thing that would have taken me a while to solve ;) Levi lstephen.wordpress.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe