Re: [Haskell-cafe] ordNub
* Anthony Cowley acow...@seas.upenn.edu [2013-10-12 15:43:57-0400] On Oct 12, 2013, at 2:47 PM, Niklas Hambüchen m...@nh2.me wrote: I would like to come back to the original question: How can ordNub be added to base? I guess we agree that Data.List is the right module for a function of type Ord a = [a] - [a], but this introduces * a cyclic dependency between Data.List and Data.Set * a base dependency on containers. What is the right way to go with that? Should ordNub be introduced as part of Data.Set, as Conrad suggested? It does not really have anything to do with Set, apart from being implemented with it. I think nub's behavior is rather set-related, so I don't really understand the objection to putting it in Data.Set. It's not Set (in the data structure sense) related. It's list-related, because it clearly acts on lists. Therefore, it belongs to Data.List. Besides, we already have the precedent of the slow nub being in Data.List. Roman signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Using lenses
Hi Simon, An interesting use case is my time-lens library. http://hackage.haskell.org/package/time-lens-0.3/docs/Data-Time-Lens.html You can do things like modL minutes (+5) (TimeOfDay 16 57 13) 17:02:13 But one has to be somewhat lenient about the lens laws here. Roman * Simon Peyton-Jones simo...@microsoft.com [2013-10-03 08:07:12+] (I sent this to 'libraries' but Kim-Ee suggested adding Café, where so many smart people hang out.) Friends Some of you will know that I've promised to give a talk about Edward's lens libraryhttp://hackage.haskell.org/package/lens at the Haskell Exchangehttp://skillsmatter.com/event/scala/haskell-exchange in London next Wednesday (9th). I did this to give everyone (including me) a break from GHC hackery, and also to force me to learn about this lens voodoo that everyone is twittering about. Edward generously gave me quite a bit of one-to-one attention last week (my hair is still standing on end), but this message is to ask your help too. Specifically, I'd like to give some compelling use-cases. If you are using the lens library yourself, could you spare a few minutes to tell me how you are using it? I expect to cover Lens and Traversal but not Prism. The use-case everyone starts with is nested records, but I'd like to go beyond that. The next levels seem to be: · Lenses as views of data that isn't really there e.g. regarding a record with rectangular coordinates as having polar coordinates too. · Lenses and Traversals that focus on elements of finite maps (Control.Lens.At) What else? I'm sure you are using them in all sorts of cool ways that I would never think of, and I'd love to know. Please don't tell me anything secret! To give everyone the benefit I may just concatenate all the replies and send to you all, so please say if you don't want me to do that with yours. And don't burn too many cycles on this...I don't want to waste your time, and I can always get back to you if I can't understand what you say. Sooner is better than later...Weds is coming. Simon Edward's prophet PJ ___ Libraries mailing list librar...@haskell.org http://www.haskell.org/mailman/listinfo/libraries ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [ANN] lvish 1.0 -- successor to monad-par
Ryan, You can use standalone-haddock[1] so that the links to other packages are not broken. [1]: http://documentup.com/feuerbach/standalone-haddock Roman * Ryan Newton rrnew...@gmail.com [2013-10-03 10:50:47-0400] Hi Ben, We made a small update releasehttp://hackage.haskell.org/package/lvish-1.0.0.2that links the github, and also links a mirror for the haddocks, since something weird seems to be going on with Hackage 2: http://www.cs.indiana.edu/~rrnewton/haddock/lvish/ https://github.com/iu-parfunc/lvars On Wed, Oct 2, 2013 at 1:05 PM, Ben Gamari bgamari.f...@gmail.com wrote: Ryan Newton rrnew...@gmail.com writes: Hi all, I'm pleased to announce the release of our new parallel-programming library, LVish: hackage.haskell.org/package/lvish It provides a Par monad similar to the monad-par package, but generalizes the model to include data-structures other than single-assignment variables (IVars). For example, it has lock-free concurrent data structures for Sets and Maps, which are constrained to only grow monotonically during a given runPar (to retain determinism). This is based on work described in our upcoming POPL 2014 paper: Do you have any aidea why the Haddocks don't yet exist. If I recall correctly, under Hackage 1 the module names wouldn't be made links until Haddock generation had completed. Currently the lvish modules' point to non-existent URLs. Also, is there a publicly accessible repository where further development will take place? Cheers, - Ben ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] indentation with let and do
On Thu, Oct 3, 2013 at 9:44 PM, Brandon Allbery allber...@gmail.com wrote: On Thu, Oct 3, 2013 at 2:31 PM, Corentin Dupont corentin.dup...@gmail.com wrote: test :: Bool - IO () test foo = do let bar = case foo of True - Foo; False - Bar return () while this one does (just adding one space in front of True and False): test :: Bool - IO () test foo = do let bar = case foo of True - Foo; False - Bar return () Do you understand how layout works? Informally, something that is more indented is a continuation of the previous expression, while something equally or less indented is a new expression. In this case, the previous expression is `bar = case foo of` and indenting `True` to the same level as `bar` means you have ended the expression starting with `bar =`. Adding just one extra space indicates that it's still part of `bar =`. (ghc is actually being somewhat lenient here; strictly speaking, you are not indented beyond the `case` so it should have ended the `case` expression. ghc allows some sloppiness like this when there absolutely must be something else after, but there are limits mostly imposed by layout introducers like `let` and `do`.) Brandon, Indentation of 'case' itself doesn't matter. The layout is introduced by 'of', and then it's the indentation of the lexeme which follows 'of' that matters. So GHC is correct here. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Any precedent or plan for guaranteed-safe Eq and Ord instances?
* Heinrich Apfelmus apfel...@quantentunnel.de [2013-10-02 11:24:39+0200] In other words, equality of abstract data types is different from equality of algebraic data types (constructors). I don't think you'll ever be able to avoid this proof obligation that the public API of an abstract data type preserves equivalence, so that LVish will yield results that are deterministic up to equivalence. It still seems to fit nicely into Safe Haskell. If you are the implementor of an abstract type, you can do whatever you want in the Eq instance, declare your module as Trustworthy, and thus take the responsibility for soundness of that instance w.r.t. your public API. Roman signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Any precedent or plan for guaranteed-safe Eq and Ord instances?
* Tillmann Rendel ren...@informatik.uni-marburg.de [2013-10-02 13:19:38+0200] Hi, Roman Cheplyaka wrote: It still seems to fit nicely into Safe Haskell. If you are the implementor of an abstract type, you can do whatever you want in the Eq instance, declare your module as Trustworthy, and thus take the responsibility for soundness of that instance w.r.t. your public API. A possible problem with marking instance Eq as an unsafe feature is that many modules would be only Trustworthy instead of Safe. So if I don't trust the authors of a module (because I don't know them), I cannot safely use their code just because they implement their own Eq instance? That would go against my every purely functional module is automatically safe because the compiler checks that it cannot launch the missiles understanding of Safe Haskell. Actually, Eq instances are not unsafe per se, but only if I also use some other module that assumes certain properties about all Eq instances in scope. So in order to check safety, two independent modules (the provider and the consumer of the Eq instance) would have to cooperate. Good point! Roman signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Any precedent or plan for guaranteed-safe Eq and Ord instances?
* Stijn van Drongelen rhym...@gmail.com [2013-10-02 15:46:42+0200] I do think something has to be done to have an Eq and Ord with more strict laws. * Operators in Eq and Ord diverge iff any of their parameters are bottom. This outlaws the Eq instances of lists, trees, and other (co)recursive types. Furthermore, in this formulation, even Eq for tuples is illegal, because (undefined, something) == somethingElse is going to diverge. Roman signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Lifting IO actions into Applicatives
* Tom Ellis tom-lists-haskell-cafe-2...@jaguarpaw.co.uk [2013-10-01 09:20:23+0100] On Tue, Oct 01, 2013 at 09:29:00AM +0200, Niklas Haas wrote: On Tue, 1 Oct 2013 02:21:13 -0500, John Lato jwl...@gmail.com wrote: It's not a solution per se, but it seems to me that there's no need for the Monad superclass constraint on MonadIO. If that were removed, we could just have class LiftIO t where liftIO :: IO a - t a and it would Just Work. One concern with this is that it's not exactly clear what the semantics are on LiftIO (is liftIO a liftIO b equal to liftIO (a b) or not?) and the interaction between LiftIO and Applicative/Monad would have to be some sort of ugly ad-hoc law like we have with Bounded/Enum etc. Shouldn't it be an *Applicative* constraint? class Applicative t = ApplicativeIO t where liftIO :: IO a - t a and require that liftIO (pure x) = pure x liftIO (f * x) = liftIO f * liftIO x Seems like ApplicativeIO makes more sense than MonadIO, which is unnecessarily restrictive. With planned Functor/Applicative/Monad shuffle, the former could completely replace the latter. Agreed, this makes perfect sense. It simply says that liftIO is an applicative homomorphism. Roman signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Haskell.org design is broken
There is now a big white stripe in the Haskell.org's header (see the screenshot). Roman attachment: haskellorg.png signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Multi-param typeclass vs locally constrained typeclass methods
* Jacques Carette care...@mcmaster.ca [2013-09-18 08:21:51-0400] Could someone please explain what the difference (if any!), in semantics is between class Foo f = Bar f g where method1 :: f a - g a and class Bar' g where method2 :: Foo f = f a - g a Bar is more flexible than Bar'. If you have n types, you can write n^2 Bar instances (potentially having very different semantics) to convert between them. You can only write n Bar' instances, on the other hand. In these instances you can dispatch based on 'g' but not on 'f'. 'f' is abstract, and you only can access it through the Foo interface. So they are quite different. Roman signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] name lists
* Ben Gamari bgamari.f...@gmail.com [2013-09-17 10:03:41-0400] Another approach might be to introduce some notion of a name list which can appear in the export list. These lists could be built up by either user declarations in the source module or in Template Haskell splices and would serve as a way to group logically related exports. This would allow uses such as (excuse the terrible syntax), module HelloWorld ( namelist MyDataLenses , namelist ArithmeticOps ) where import Control.Lens data MyData = MyData { ... } makeLenses ''MyDataLenses -- makeLenses defines a namelist called MyDataLenses namelist ArithmeticOps (add) add = ... namelist ArithmeticOps (sub) sub = ... Hi Ben, Isn't this subsumed by ordinary Haskell modules, barring the current compilers' limitation that modules are in 1-to-1 correspondence with files (and thus are somewhat heavy-weight)? E.g. the above could be structured as module MyDataLenses where data MyData = MyData { ... } makeLenses ''MyData module HelloWorld (module MyDataLenses, ...) where ... Roman signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] name lists
* Ben Gamari bgamari.f...@gmail.com [2013-09-17 12:41:05-0400] Roman Cheplyaka r...@ro-che.info writes: * Ben Gamari bgamari.f...@gmail.com [2013-09-17 10:03:41-0400] Another approach might be to introduce some notion of a name list which can appear in the export list. These lists could be built up by either user declarations in the source module or in Template Haskell splices and would serve as a way to group logically related exports. This would allow uses such as (excuse the terrible syntax), Hi Ben, Isn't this subsumed by ordinary Haskell modules, barring the current compilers' limitation that modules are in 1-to-1 correspondence with files (and thus are somewhat heavy-weight)? E.g. the above could be structured as module MyDataLenses where data MyData = MyData { ... } makeLenses ''MyData module HelloWorld (module MyDataLenses, ...) where ... True. Unfortunately I've not seen much motion towards relaxing this limitation[1]. Cheers, - Ben [1] http://ghc.haskell.org/trac/ghc/ticket/2551 I guess there simply were not many use cases for that. This may be one. At least if we are talking about changing the compiler anyway, it's better to stick with a well-understood and standardized mechanism. Roman signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Proposal: New syntax for Haskell
* John Wiegley jo...@fpcomplete.com [2013-09-10 04:48:36-0500] Niklas Hambüchen m...@nh2.me writes: Code written in cucumber syntax is concise and easy to read concise |kənˈsīs|, adj. giving a lot of information clearly and in a few words; brief but comprehensive. Compare: Scenario: Defining the function foldl Given I want do define foldl Which has the type (in brackets) a to b to a (end of brackets), to a, to list of b, to a And my arguments are called f, acc, and l When l is empty Then the result better be acc Otherwise l is x cons xs Then the result should be foldl f (in brackets) f acc x (end of brackets) xs To: foldl :: (a - b - a) - a - [b] - a foldl f z [] = z foldl f z (x:xs) = foldl f (f z x) xs How is that more concise or preferable? I thought it was a joke. Roman signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] GHC API + Cabal API + Cabal version checks: is there a way out?
The right solution for Cabal would be not to know anything about the GHC's database format at all. GHC and cabal communicate via a command line interface (`ghc-pkg dump` in our direction; `ghc-pkg update` in the other). So it would suffice to have a library which implements parsing and printing of the package description, and have that library shared between GHC and Cabal. (Which I think is more or less what you guys are suggesting, only I'd like to point out that we should be focusing on the protocol instead of the database format. The latter should be opaque.) Roman * Niklas Hambüchen m...@nh2.me [2013-09-06 22:42:28+0900] On Fri 06 Sep 2013 22:13:58 JST, Yuri de Wit wrote: The right solution, imho, is to review these dependencies and move the low level ones out into a separate package that is shared by both ghc and cabal and that will rarely change. The direct side effect of this is that ghc would not be tied directly to a specific cabal version and you would not have to deal with this issue. This sounds very right to me. There should be something that describes what a GHC package database is, as minimally as possible (perhaps even only the data types). In the end, ghc is the defining side here - cabal is only a tool that builds on top of these definitions. Then ghc could finally be decoupled from Cabal. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] a little parsec enhancement
* Petr Pudlák petr@gmail.com [2013-09-05 11:18:25+0200] Unfortunately |ParsecT| constructor isn't exported so I'm not able to implement it outside /parsec/. No, but there's an 'mkPT' function which is equivalent to the ParsecT constructor. (Although I, too, wish the ParsecT constructor were exposed.) Roman signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] function arithmetic?
* Christopher Howard christopher.how...@frigidcode.com [2013-08-31 21:01:38-0800] Hi. I was just curious about something. In one of my math textbooks I see expressions like this f + g or (f + g)(a) where f and g are functions. What is meant is f(a) + g(a) Is there a way in Haskell you can make use of syntax like that (i.e., expressions like f + g and f * g to create a new function), perhaps by loading a module or something? Not the syntax, but the notion itself corresponds exactly to idiom brackets/applicative functors. In this case it's the Reader applicative. Roman signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Tasty not compiling
* Thiago Negri evoh...@gmail.com [2013-08-29 22:27:47-0300] I can't install tasty with cabal. Anyone with the same issue or a fix? $ cabal install tasty ... Test\Tasty\Core.hs:147:11: Not in scope: `witness' You probably have a too old version of 'tagged'. I'll add the lower version bound on it. Meanwhile, just do cabal install tasty --constraint 'tagged =0.5' Roman signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] A question about laziness and performance in document serialization.
* Kyle Hanson hanoo...@gmail.com [2013-08-20 18:23:48-0700] So I am not entirely clear on how to optimize for performance for lazy bytestrings. Currently I have a (Lazy) Map that contains large BSON values (more than 1mb when serialized each). I can serialize BSON documents to Lazy ByteStrings using Data.Binary.runPut. I then write this bytestring to a socket using Network.Socket.ByteString.Lazy. My question is this, if the Map object doesn't change (no updates) when it serializes the same document to the socket 2x in a row, does it re-evaluate the whole BSON value and convert it to a bytestring each time? Yes. Lets say I wanted to have a cache of bytestings so I have another Map object that has the serialized bytestrings that I populate it with every time the original BSON Map changes. Should the map be strict or lazy? This is the wrong question. The right question is, do you want the values be strict (evaluated) or lazy (kept unevaluated until required)? If you want values to be lazy, then you have to use the lazy Map. If you want values to be strict, then you may either use the strict Map, or still use the lazy Map but make sure that the values are evaluated when you place them in the map. Using the strict Map is probably a better idea, but the lazy Map lets you have finer control over what is lazy and what is forced (should you need it). Note that the lazy bytestring is just a lazy list of strict bytestrings. Even placing it in the strict map wouldn't force its evaluation. Should the bytestrings it stores be strict or lazy? For a cache, it makes sense to store strict bytestrings (unless they are so large that it may be hard to allocate that much of contiguous space). Lazy bytestrings are useful for streaming, when you use a chunk and then discard it. Using strict bytestrings doesn't imply that you want to store them evaluated. Depending on your circumstances, it may be a good idea to store strict bytestrings lazily, so that they do not take space and time until they are requested for the first time. Simply operating with the words lazy and strict may be very confusing, since they refer to different things in different contexts. Every time you read that something is lazy or strict, try to decipher it in terms of the basic evaluation properties. HTH, Roman signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANN: hspec-test-framework - Run test-framework tests with Hspec
My answer to this and many similar questions regarding tasty is: - I am probably not going to work on this - but I would be happy to see someone doing it Note that hspec-test-framework is a separate package, and it didn't have to be written or even approved by Simon. Same here — please write more supplementary packages if you feel a need. Roman * Alfredo Di Napoli alfredo.dinap...@gmail.com [2013-08-18 15:18:07+0200] Hi Simon, this is an exciting news! May I ask the question that maybe is lurking in the shadow? Due to the recent announcement of Roman's tasty library, are there plans to basically release something similar to hspec-test-framework and hspec-test-framework-th but targeting tasty instead? Bye :) A. On 18 August 2013 14:50, Simon Hengel s...@typeful.net wrote: Hi, I just released hspec-test-framework[1] and hspec-test-framework-th[2] to Hackage. They can be used to run test-framework tests with Hspec unmodified. This can also be used to work around test-framework's incompatibility with QuickCheck-2.6 and base-4.7.0 ;) Have a look at the README for usage instructions: https://github.com/sol/hspec-test-framework#readme Cheers, Simon [1] http://hackage.haskell.org/package/hspec-test-framework [2] http://hackage.haskell.org/package/hspec-test-framework-th ___ 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 signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haddock multiple definitions
* Mateusz Kowalczyk fuuze...@fuuzetsu.co.uk [2013-08-16 08:16:35+0100] In the future, please try with more recent version of GHC. This is no longer a parse error with HEAD or 7.6.3. Uhm, actually there is, with 7.6.3. % cat haddock.hs -- Main -- | Blah blah blah (x, y, z) = (1, 2, 3) % haddock haddock.hs haddock.hs:4:1: parse error on input `(' % haddock --version Haddock version 2.13.2, (c) Simon Marlow 2006 Ported to use the GHC API by David Waern 2006-2008 It's great that it's fixed in HEAD. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haddock multiple definitions
In any case, it shouldn't fail with a parse error, since this is valid Haskell. Please file a ticket at http://trac.haskell.org/haddock (but first see if it hasn't been reported before). Roman * jabolo...@google.com jabolo...@google.com [2013-08-15 15:24:23-0400] Hi, I am using GHC: 6.12.1 Haddock: 2.6.0 and the following does not work with Haddock (GHC is fine!): -- Main -- | Blah blah blah (x, y, z) = (1, 2, 3) $ haddock ... /tmp/Main.hs:2:0: parse error on input `(' Is this a bug? Or it's just not part of Haddock? This seems like an interesting feature to document several definitions together, for example, error codes: -- | Syscall error codes for blah... -- -- errA when blah -- ... (errA, errB, errC) = ... Cheers, Jose ___ 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
Re: [Haskell-cafe] Module names from a function name
Hi, You can easily do this using the haskell-names library. See http://documentup.com/haskell-suite/haskell-names Roman * Jong-won Choi oz.jongwon.c...@gmail.com [2013-08-08 12:34:44+1000] Hi, I asked this question to beginner mailing list and no luck so far, so I'm trying here. How can I get all the module names which (re-)export a given function name? I'd like to fix Emacs Haskell mode - interactive documentation browser and I need the list of such module names. Thanks! - Jong-won ___ 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
Re: [Haskell-cafe] ANNOUNCE: tasty, a new testing framework
* Magnus Therning mag...@therning.org [2013-08-08 07:59:37+0200] On Mon, Aug 05, 2013 at 09:48:39PM +0300, Roman Cheplyaka wrote: I am pleased to announce the first release of tasty, a new testing framework for Haskell. It is meant to be a successor to test-framework (which is unmaintained). Tasty supports HUnit, SmallCheck, QuickCheck, and golden tests out of the box (through the standard packages), but it is very extensible, so you can write your own test providers. Please see the home page for more information: http://documentup.com/feuerbach/tasty Are there plans an equivalent of test-framework-th too? I don't have any plans to do that myself, but I welcome anyone who cares to create and maintain such a package. donri on reddit said that porting test-framework-th should be a simple matter of changing one import. Roman signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Installing wxHaskel on Snow Leopard
* Eduardo Sato eduardo.s...@gmail.com [2013-08-07 14:46:02-0300] Hello, guys. Has anybody tried to install wxhaskell on Snow Leopard? I followed these instructions: http://www.haskell.org/haskellwiki/WxHaskell/Mac , but got an error: src/haskell/Graphics/UI/WXCore/WxcClassesAL.hs:13085:1: Unacceptable argument type in foreign declaration: CInt When checking declaration: foreign import ccall safe static wxLogWindow_Create wxLogWindow_Create :: Ptr (TWindow a) - CWString - CBool - CBool - IO (Ptr (TLogWindow ())) src/haskell/Graphics/UI/WXCore/WxcClassesAL.hs:13085:1: Unacceptable argument type in foreign declaration: CInt When checking declaration: foreign import ccall safe static wxLogWindow_Create wxLogWindow_Create :: Ptr (TWindow a) - CWString - CBool - CBool - IO (Ptr (TLogWindow ())) Failed to install wxcore-0.90.0.3 cabal: Error: some packages failed to install: wx-0.90.0.1 depends on wxcore-0.90.0.3 which failed to install. wxcore-0.90.0.3 failed during the building phase. The exception was: ExitFailure 1 http://lpaste.net/91634 I'm using ghc 7.6.3. I've heard the above problems are related to GHC 7.6.3 being more pedantic about FFI declarations. Is there any way around it? Indeed, and it has nothing to do with Snow Leopard. You should ensure that the CInt data constructor is imported. Either patch it yourself, or have the package maintainer to fix it. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANNOUNCE: tasty, a new testing framework
It certainly can, but it doesn't do that yet. Should be very easy to fix, though. Patches are welcome. Roman * Jan Stolarek jan.stola...@p.lodz.pl [2013-08-07 10:00:36+0200] Sorry, my last email got sent too quickly. Anyway, continuing my thought. So QuickCheck can classify tests: +++ OK, passed 100 tests (29% Short) Can tasty display this classification info? That was a thing I missed a lot in test-framework and would probably motivate me to switch to tasty. Janek - Oryginalna wiadomość - Od: Roman Cheplyaka r...@ro-che.info Do: haskell-cafe@haskell.org Wysłane: wtorek, 6 sierpień 2013 22:51:57 Temat: Re: [Haskell-cafe] ANNOUNCE: tasty, a new testing framework * John Wiegley jo...@fpcomplete.com [2013-08-06 13:40:50-0500] Roman Cheplyaka r...@ro-che.info writes: I am pleased to announce the first release of tasty, a new testing framework for Haskell. It is meant to be a successor to test-framework (which is unmaintained). It would be nice to see a comparison of the various test frameworks and why one might select one over another. I use hspec currently (which also integrates with HUnit, QuickCheck, etc.), and couldn't tell at a glance what tasty might offer. And I particularly dislike writing tests inside of a gigantic list; I much prefer the monadic style of hspec. This has been discussed on reddit here: http://www.reddit.com/r/haskell/comments/1jr8lb/tasty_a_new_testing_framework_successor_to/cbhiz40 Roman ___ 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
Re: [Haskell-cafe] ANNOUNCE: tasty, a new testing framework
You can find an example here: https://github.com/feuerbach/regex-applicative/blob/master/regex-applicative.cabal#L89 If you'd like to contribute a short README section based on that, please go ahead! :) Roman * Tikhon Jelvis tik...@jelv.is [2013-08-06 09:29:21-0400] Could you add some documentation on how to use this with cabal? I've found integrating tests with cabal unintuitive and poorly documented--to the point where I haven't really bothered! I've gotten it working before, but I would have to look it up again in the future. (I also didn't use a framework.) It would be awesome to see an example .cabal file along with your example test cases. thanks, -tikhon On Tue, Aug 6, 2013 at 1:53 AM, Roman Cheplyaka r...@ro-che.info wrote: * Carter Schonwald carter.schonw...@gmail.com [2013-08-05 16:58:37-0400] fair enough. I take it that you're also (implicitly) committing to maintaining this for the next few years? :) That's correct. Roman ___ 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
Re: [Haskell-cafe] ANNOUNCE: tasty, a new testing framework
* John Wiegley jo...@fpcomplete.com [2013-08-06 13:40:50-0500] Roman Cheplyaka r...@ro-che.info writes: I am pleased to announce the first release of tasty, a new testing framework for Haskell. It is meant to be a successor to test-framework (which is unmaintained). It would be nice to see a comparison of the various test frameworks and why one might select one over another. I use hspec currently (which also integrates with HUnit, QuickCheck, etc.), and couldn't tell at a glance what tasty might offer. And I particularly dislike writing tests inside of a gigantic list; I much prefer the monadic style of hspec. This has been discussed on reddit here: http://www.reddit.com/r/haskell/comments/1jr8lb/tasty_a_new_testing_framework_successor_to/cbhiz40 Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] ANNOUNCE: tasty, a new testing framework
I am pleased to announce the first release of tasty, a new testing framework for Haskell. It is meant to be a successor to test-framework (which is unmaintained). Tasty supports HUnit, SmallCheck, QuickCheck, and golden tests out of the box (through the standard packages), but it is very extensible, so you can write your own test providers. Please see the home page for more information: http://documentup.com/feuerbach/tasty Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANNOUNCE: tasty, a new testing framework
* Andrey Chudnov achud...@gmail.com [2013-08-05 15:31:16-0400] On 08/05/2013 02:48 PM, Roman Cheplyaka wrote: (which is unmaintained). Has this been confirmed by the author/maintainer? I've sent a couple of emails to Max (one in January, one in April) and haven't heard anything from him. My patches, which he applied in January, are still not released. That's why I regard test-framework as unmaintained. You can also make your own impression by browsing github (commit activity, outstanding pull requests, open issues...) Is it a drop-in replacement for test-framework, e.g. if I substitute test-framework for tasty in my .cabal files, will it work? If not, could you provide a quick guide for porting? Not quite. At the very least, you'll have to change module names (Test.Framework - Test.Tasty, Test.Framework.Providers.HUnit - Test.Tasty.HUnit, ...), and wrap the top-level list of tests into a testGroup. If you have type signatures, you'll need to rename Test to TestTree. That should be enough in most cases. If you use plusTestOptions, you'll need to look up appropriate functions from Test.Tasty.Options. Also, is the current version (0.1) recommended for general use? I'd love to see people using it. But you should treat this as beta software. I am in the process of migrating my own packages to use Tasty. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANNOUNCE: tasty, a new testing framework
* Carter Schonwald carter.schonw...@gmail.com [2013-08-05 16:58:37-0400] fair enough. I take it that you're also (implicitly) committing to maintaining this for the next few years? :) That's correct. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Why GHC is written in Happy and not a monadic parser library?
* Malcolm Wallace malcolm.wall...@me.com [2013-08-04 09:33:22+0100] On 3 Aug 2013, at 21:03, Jason Dagit wrote: Another con of using parsec that I forgot to mention in my previous email is that with Parsec you need to be explicit about backtracking (use of try). Reasoning about the correct places to put try is not always easy and parsec doesn't help you with the task. In my experience, this is the main bug that people run into when using parsec. Although the original question did not mention parsec explicitly, I find it disappointing that many people immediately think of it as the epitome of monadic combinator parsing. The power of good marketing, eh? There are so many other good parsing libraries out there. Parsec happened to cure some known space-leaks in rival libraries about the time of its release (2000 or so), but the main reason it is popular is simply because it was distributed alongside ghc for a long time. I would also add to this a catchy and well-marketed name, which is often used as a generic name for a parser combinator library. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Rank N Kinds
That's because types that belong to most non-star kinds cannot have values. data Foo (a :: k) = Foo is okay, data Foo (a :: k) = Foo a is bad because there cannot be a field of type a :: k. So no, no useful examples exist, because you wouldn't be able to use such a data constructor even if you could declare it. Roman * Wvv vite...@rambler.ru [2013-07-31 11:40:17-0700] OMG! I still have 7.6.3. It has old Typeable. I misunderstood PolyKinds a bit. It looks like k /= **, k ~ ***... But we cannot use CloseKinds like data Foo (a::k) = Foo a -- catch an error Expected kind `OpenKind', but `a' has kind `k' with RankNKinds we could write: data Foo (a::**) = Foo a data Bar (a::***) = Bar a So, now the task is more easy: I'm asking for useful examples with CloseKinds with ** and higher, and any useful examples for *** and higher cheers, Wvv 29 Jul 2013 at 14:44:50, José Pedro Magalhães [via Haskell] (ml-node+s1045720n5733561...@n5.nabble.com) wrote: Hi, On Fri, Jul 26, 2013 at 10:42 PM, Wvv [hidden email] wrote: First useful use is in Typeable. In GHC 7.8 class Typeable (a::k) where ... == class Typeable (a ::**) where ... But we can't write data Foo (a::k)-(a::k)-* ... deriving Typeable Why not? This works fine in 7.7, as far as I know. Cheers, Pedro -- View this message in context: http://haskell.1045720.n5.nabble.com/Rank-N-Kinds-tp5733482p5733667.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. ___ 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
Re: [Haskell-cafe] Haddock GSOC project progress
Hi Mateusz, This looks great — I'm especially excited about List entries no longer have to be separated by empty lines! However, the decision to use Attoparsec (instead of Parsec, say) strikes me as a bit odd, as it wasn't intended for parsing source code. In particular, I'm concerned with error messages this parser would produce. Roman * Mateusz Kowalczyk fuuze...@fuuzetsu.co.uk [2013-07-30 23:35:45+0100] Greetings cafe, As some of you might know, I'm hacking on Haddock as part of Google Summer of Code. I was recently advised to create a blog and document some of what I have been doing recently. You can find the blog at [1] if you're interested. The first post goes over the work from the last month or so. Future posts should be shorter and on more specific topics. There's an overview of what has happened/changed/will change at the bottom of the post if you're short on time. Thanks. [1] - http://fuuzetsu.co.uk/blog ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Is withAsync absolutely safe?
* Bertram Felgenhauer bertram.felgenha...@googlemail.com [2013-07-28 18:11:54+0200] Roman Cheplyaka wrote: Can withAsync guarantee that its child will be terminated if the thread executing withAsync gets an exception? To remind, here's an implementation of withAsync: withAsyncUsing :: (IO () - IO ThreadId) - IO a - (Async a - IO b) - IO b -- The bracket version works, but is slow. We can do better by -- hand-coding it: withAsyncUsing doFork = \action inner - do var - newEmptyTMVarIO mask $ \restore - do t - doFork $ try (restore action) = atomically . putTMVar var let a = Async t (readTMVar var) r - restore (inner a) `catchAll` \e - do cancel a; throwIO e cancel a return r I am interested in the case when an exception arrives which transfers control to 'cancel', and then another exception arrives to the same thread. Even though 'catchAll' (which is a type-restricted synonym for catch) masks the exception handler, 'throwTo' inside 'cancel' is interruptible (as stated by the documentation). Will this scenario lead to a thread leakage? Yes. I guess that 'cancel' should use 'uninterruptibleMask_', but it's a hard call to make (if an async action becomes unresponsive, do we want to risk not being able to deliver any exceptions to the controlling thread just because it wants to terminate the async action?) Fair point. What if we fork a new thread, shield it from exceptions using uninterruptibleMask_, and let it to kill every other thread (however long that may take)? It will change the semantics a bit (the cleanup will be asynchronous), but I'm not sure if it can be a problem. A hybrid (but complicated) approach should also be possible. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Is withAsync absolutely safe?
Can withAsync guarantee that its child will be terminated if the thread executing withAsync gets an exception? To remind, here's an implementation of withAsync: withAsyncUsing :: (IO () - IO ThreadId) - IO a - (Async a - IO b) - IO b -- The bracket version works, but is slow. We can do better by -- hand-coding it: withAsyncUsing doFork = \action inner - do var - newEmptyTMVarIO mask $ \restore - do t - doFork $ try (restore action) = atomically . putTMVar var let a = Async t (readTMVar var) r - restore (inner a) `catchAll` \e - do cancel a; throwIO e cancel a return r I am interested in the case when an exception arrives which transfers control to 'cancel', and then another exception arrives to the same thread. Even though 'catchAll' (which is a type-restricted synonym for catch) masks the exception handler, 'throwTo' inside 'cancel' is interruptible (as stated by the documentation). Will this scenario lead to a thread leakage? Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Parsec question
Think about this: if you always take only the first element, why do you need lists at all? Roman * C K Kashyap ckkash...@gmail.com [2013-07-24 19:56:29+0530] Dear Cafe, I am trying to implement[1] parsec in go using the Monadic Parser Combinators paper [2] . I've been able to implement plus bind and many While doing the implementation - I looked at bind closely bind :: Parser a - (a - Parser b) - Parser b p `bind` f = \inp - concat [f v inp' | (v,inp') - p inp] I wondered if the result needs the complete list - wouldn't just the first successful value suffice? Perhaps - p `bind` f = \inp - take 1 $ concat [f v inp' | (v,inp') - p inp] Will this miss out matches? Regards, Kashyap [1] https://github.com/ckkashyap/parsec/blob/master/parsec.go [2] Monadic Parser Combinators: Graham Hutton, Erik Meijer ___ 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
Re: [Haskell-cafe] Parsec question
To construct such an example, you have to ask yourself: when can we get a list of more than one element? Consider this: a = char 'a' ((a a) | a) a Suppose that our input is aa. The result of ((a a) | a) would be the list [('a', ), ('a', a)] If you proceed with the first element of the list, the overall parse will fail. It can only succeed if you then try the second element. By the way, you shouldn't confuse Parsec (the library) with the general concept of parser combinators or the implementation from the paper you reference. The above parse would fail in Parsec as well, despite the fact that Parsec allows backtracking. Roman * Kashyap CK ckkash...@gmail.com [2013-07-24 08:38:53-0700] There is reference in the paper that empty list indicates failure...so could we just use it like Maybe? I'd like it very much if I could get an example of a missed match by not using the complete match. regards, Kashyap Sent from my Windows Phone From: Roman Cheplyaka Sent: 24/07/2013 8:19 PM To: C K Kashyap Cc: Haskell Cafe Subject: Re: [Haskell-cafe] Parsec question Think about this: if you always take only the first element, why do you need lists at all? Roman * C K Kashyap ckkash...@gmail.com [2013-07-24 19:56:29+0530] Dear Cafe, I am trying to implement[1] parsec in go using the Monadic Parser Combinators paper [2] . I've been able to implement plus bind and many While doing the implementation - I looked at bind closely bind :: Parser a - (a - Parser b) - Parser b p `bind` f = \inp - concat [f v inp' | (v,inp') - p inp] I wondered if the result needs the complete list - wouldn't just the first successful value suffice? Perhaps - p `bind` f = \inp - take 1 $ concat [f v inp' | (v,inp') - p inp] Will this miss out matches? Regards, Kashyap [1] https://github.com/ckkashyap/parsec/blob/master/parsec.go [2] Monadic Parser Combinators: Graham Hutton, Erik Meijer ___ 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
Re: [Haskell-cafe] Deriving with generics without values
Forgot to mention — a good explanation of GHC Generics is the paper A Generic Deriving Mechanism for Haskell. Roman * Roman Cheplyaka r...@ro-che.info [2013-07-14 18:21:58+0300] Hi, (Redirecting this back to cafe to keep it discoverable — hope you don't mind.) * JP Moresmau jpmores...@gmail.com [2013-07-14 16:02:56+0200] Hello, sorry to bother you after you've been kind enough to answer me on the list! I've looked a the smallcheck code but I don't see how to apply it to my issue. First of all, I can't find the definition of - that you use for example in ~. I suppose I'm doing something silly... That comes from LogicT. - is almost the same as =, and ~ is almost the same as *. Byt that's not relevant to the generic aspect of the code. But then, if I understand the code, the instances for GSerial rebuild a type definition that mimicks the one passed as type argument, using the final values (under the K1s) to generate a series. But in my case, I want to be able to extract information from the original type, I'm not just interested in the final value. What I want to be able is to extract for example the constructor name and do something with it. I don't see how to achieve that with your system. Yes, it doesn't do everything that you want to do, but it shows the idea. The information you need is all there — for example, to get the constructor name, you need to get hold of the C1 type (which is a synonym for M1 C), and then call the conName method. Lest you get lost in all this, it is useful to visualize the generic representation by running your code through -ddump-deriv. Here's an example: % ghci -XDeriveGeneric -ddump-deriv -dsuppress-module-prefixes Prelude GHC.Generics data T a = A { a :: a } | B | C deriving Generic Derived instances Derived instances: instance Generic (T a_ao7) where from (A g1_aph) = M1 (L1 (M1 (M1 (K1 g1_aph from B = M1 (R1 (L1 (M1 U1))) from C = M1 (R1 (R1 (M1 U1))) to (M1 (L1 (M1 (M1 (K1 g1_api) = A g1_api to (M1 (R1 (L1 (M1 U1 = B to (M1 (R1 (R1 (M1 U1 = C instance Datatype D1T where datatypeName _ = T moduleName _ = :Interactive instance Constructor C1_0T where conName _ = A conIsRecord _ = True instance Constructor C1_1T where conName _ = B instance Constructor C1_2T where conName _ = C instance Selector S1_0_0T where selName _ = a Generic representation: Generated datatypes for meta-information: D1T C1_0T C1_1T C1_2T S1_0_0T Representation types: type Rep (T a_ao7) = D1 D1T (C1 C1_0T (S1 S1_0_0T (Rec0 a_ao7)) :+: (C1 C1_1T U1 :+: C1 C1_2T U1)) This should give you an idea about how the structure you're dealing with looks like, and where the important information resides. I've also look at Aeson with the generic JSON parsing, but that's using SYB which is again different, and SYB doesn't seem to provide the types of the constructor fields, which I would need too... It provides the types of the constructor fields through the Typeable class, which may or may not be sufficient for your needs... Anyway, you're right in that it is a completely different approach. Roman On Fri, Jul 12, 2013 at 10:57 AM, Roman Cheplyaka r...@ro-che.info wrote: Well, in your case, you need not 'from', but 'to', in order to convert from a generic representation to yours. Take a look at how a similar task is done in SmallCheck: https://github.com/feuerbach/smallcheck/blob/master/Test/SmallCheck/Series.hs#L180 https://github.com/feuerbach/smallcheck/blob/master/Test/SmallCheck/Series.hs#L352 Roman * JP Moresmau jpmores...@gmail.com [2013-07-12 10:45:39+0200] Hello all, My problem is the following: I have my own data types, and I'd like to derive automatically instances of some type class from them. I've started looking at GHC.Generics, which offer tools to do exactly that. However, some functions of my typeclass do not take my data type as a parameter, but as a result. Basically: class MyClass where fromString :: String - a data MyData=MkMyData { myField ::Int } deriving (Generic) and I want to automatically generate the instance instance MyClass MyData, using default methods, etc. The GHC Generic class does say that it uses a from function that convert from the datatype to its representation: from :: a - Rep http://www.haskell.org/ghc/docs/7.4.1/html/libraries/ghc-prim-0.2.0.0/GHC-Generics.html#t:Rep a xfrom :: a - Rep http://www.haskell.org/ghc
Re: [Haskell-cafe] ordNub
Something like that should definitely be included in Data.List. Thanks for working on it. Roman * Niklas Hambüchen m...@nh2.me [2013-07-14 19:20:52+0800] tldr: nub is abnormally slow, we shouldn't use it, but we do. As you might know, Data.List.nub is O(n²). (*) As you might not know, almost *all* practical Haskell projects use it, and that in places where an Ord instance is given, e.g. happy, Xmonad, ghc-mod, Agda, darcs, QuickCheck, yesod, shake, Cabal, haddock, and 600 more (see https://github.com/nh2/haskell-ordnub). I've taken the Ord-based O(n * log n) implementation from yi using a Set: ordNub :: (Ord a) = [a] - [a] ordNub l = go empty l where go _ [] = [] go s (x:xs) = if x `member` s then go s xs else x : go (insert x s) xs and put benchmarks on http://htmlpreview.github.io/?https://github.com/nh2/haskell-ordnub/blob/1f0a2c94a/report.html (compare `nub` vs `ordNub`). `ordNub` is not only in a different complexity class, but even seems to perform better than nub for very small numbers of actually different list elements (that's the numbers before the benchmark names). (The benchmark also shows some other potential problem: Using a state monad to keep the set instead of a function argument can be up to 20 times slower. Should that happen?) What do you think about ordNub? I've seen a proposal from 5 years ago about adding a *sort*Nub function started by Neil, but it just died. (*) The mentioned complexity is for the (very common) worst case, in which the number of different elements in the list grows with the list (alias you don't have an N element list with always only 5 different things inside). ___ 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
Re: [Haskell-cafe] Deriving with generics without values
Hi, (Redirecting this back to cafe to keep it discoverable — hope you don't mind.) * JP Moresmau jpmores...@gmail.com [2013-07-14 16:02:56+0200] Hello, sorry to bother you after you've been kind enough to answer me on the list! I've looked a the smallcheck code but I don't see how to apply it to my issue. First of all, I can't find the definition of - that you use for example in ~. I suppose I'm doing something silly... That comes from LogicT. - is almost the same as =, and ~ is almost the same as *. Byt that's not relevant to the generic aspect of the code. But then, if I understand the code, the instances for GSerial rebuild a type definition that mimicks the one passed as type argument, using the final values (under the K1s) to generate a series. But in my case, I want to be able to extract information from the original type, I'm not just interested in the final value. What I want to be able is to extract for example the constructor name and do something with it. I don't see how to achieve that with your system. Yes, it doesn't do everything that you want to do, but it shows the idea. The information you need is all there — for example, to get the constructor name, you need to get hold of the C1 type (which is a synonym for M1 C), and then call the conName method. Lest you get lost in all this, it is useful to visualize the generic representation by running your code through -ddump-deriv. Here's an example: % ghci -XDeriveGeneric -ddump-deriv -dsuppress-module-prefixes Prelude GHC.Generics data T a = A { a :: a } | B | C deriving Generic Derived instances Derived instances: instance Generic (T a_ao7) where from (A g1_aph) = M1 (L1 (M1 (M1 (K1 g1_aph from B = M1 (R1 (L1 (M1 U1))) from C = M1 (R1 (R1 (M1 U1))) to (M1 (L1 (M1 (M1 (K1 g1_api) = A g1_api to (M1 (R1 (L1 (M1 U1 = B to (M1 (R1 (R1 (M1 U1 = C instance Datatype D1T where datatypeName _ = T moduleName _ = :Interactive instance Constructor C1_0T where conName _ = A conIsRecord _ = True instance Constructor C1_1T where conName _ = B instance Constructor C1_2T where conName _ = C instance Selector S1_0_0T where selName _ = a Generic representation: Generated datatypes for meta-information: D1T C1_0T C1_1T C1_2T S1_0_0T Representation types: type Rep (T a_ao7) = D1 D1T (C1 C1_0T (S1 S1_0_0T (Rec0 a_ao7)) :+: (C1 C1_1T U1 :+: C1 C1_2T U1)) This should give you an idea about how the structure you're dealing with looks like, and where the important information resides. I've also look at Aeson with the generic JSON parsing, but that's using SYB which is again different, and SYB doesn't seem to provide the types of the constructor fields, which I would need too... It provides the types of the constructor fields through the Typeable class, which may or may not be sufficient for your needs... Anyway, you're right in that it is a completely different approach. Roman On Fri, Jul 12, 2013 at 10:57 AM, Roman Cheplyaka r...@ro-che.info wrote: Well, in your case, you need not 'from', but 'to', in order to convert from a generic representation to yours. Take a look at how a similar task is done in SmallCheck: https://github.com/feuerbach/smallcheck/blob/master/Test/SmallCheck/Series.hs#L180 https://github.com/feuerbach/smallcheck/blob/master/Test/SmallCheck/Series.hs#L352 Roman * JP Moresmau jpmores...@gmail.com [2013-07-12 10:45:39+0200] Hello all, My problem is the following: I have my own data types, and I'd like to derive automatically instances of some type class from them. I've started looking at GHC.Generics, which offer tools to do exactly that. However, some functions of my typeclass do not take my data type as a parameter, but as a result. Basically: class MyClass where fromString :: String - a data MyData=MkMyData { myField ::Int } deriving (Generic) and I want to automatically generate the instance instance MyClass MyData, using default methods, etc. The GHC Generic class does say that it uses a from function that convert from the datatype to its representation: from :: a - Rep http://www.haskell.org/ghc/docs/7.4.1/html/libraries/ghc-prim-0.2.0.0/GHC-Generics.html#t:Rep a xfrom :: a - Rep http://www.haskell.org/ghc/docs/7.4.1/html/libraries/ghc-prim-0.2.0.0/GHC-Generics.html#t:Rep a x But I don't have a a to start from! I see from the related papers that the automatically generated code from from actually does pattern matches on constructors, so I need a value, undefined won't work. However I see
Re: [Haskell-cafe] Quick-check: how to generate arbitrary complex data?
* martin martin.drautzb...@web.de [2013-07-13 10:10:39+0200] Am 07/12/2013 09:18 AM, schrieb Roman Cheplyaka: QuickCheck's Gen is a functor. So you can generate a list, and then use fmap to add a hash to it. instance Arbitrary HashedList where arbitrary = addHashToList $ arbitrary This requires HashedList to be a new type, right? So far my code only used type synonyms. Does this mean I have to convert type synonyms into types in order to use QuickCheck? Probably. Technically, you could use OverlappingInstances to provide a special case for your lists (because they have a spcific shape), but I'd consider it a kludge in this case. Or you can avoid defining an instance at all, as Aleksey has pointed out. Does this mean I have to plan for QuickCheck when I design my types? Kind of. It's not really specific to QuickCheck. Every time you want to give some non-standard instances to your types, you should be using newtypes or data-types. More generally, you should be using newtypes or data types every time when you introduce a non-trivial abstraction that isn't described by the standard types. You case is a good example of that. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] getting haddock to cooperate with cpp
This is not true either. Cabal preprocesses files that explicitly indicate (via an extension) that they need to be preprocessed. For example, a .cpphs file will be preprocessed to yield an .hs file. .hs files are never preprocessed by Cabal, as far as I can tell. If you have an .hs file with {-# LANGUAGE CPP #-}, it is a compiler's job to detect it and run the preprocessor. But haddock uses the GHC API (which knows how to do the above), so there shouldn't be issues with that. Roman * Felipe Almeida Lessa felipe.le...@gmail.com [2013-07-12 18:34:32-0300] I guess that cabal preprocesses the files before calling Haddock then. Perhaps that's why it asks me to `cabal configure` before `cabal haddock`ing =). If you're able to switch over to cabal, that may be the easiest solution. Cheers, On Fri, Jul 12, 2013 at 6:31 PM, Evan Laforge qdun...@gmail.com wrote: I'm calling haddock myself. Cabal might have some special magic for CPP, when I searched for haddock CPP I got some old bugs about adding cabal support. So presumably it's possible. On Jul 12, 2013 1:15 PM, Felipe Almeida Lessa felipe.le...@gmail.com wrote: Are you using `cabal haddock` or calling haddock manually? Cheers, On Fri, Jul 12, 2013 at 3:25 PM, Evan Laforge qdun...@gmail.com wrote: So haddock ignores {-# LANGUAGE CPP #-}, which makes it crash on any file that uses it. But if you pass --optghc=-cpp, it runs CPP on everything, which makes it crash on any file that uses string gaps, or happens to contain a /*. /* is rare and easily fixed, but not string gaps. It looks like a workaround would be to manually inspect the files for LANGUAGE CPP and run two haddock passes, but then I would have to get the two passes to cooperate creating a single TOC and index. Isn't there some way to run haddock on files that use CPP? In the broader scheme, it seems perverse to be using CPP in the first place. I use it to configure imports and exports, e.g. to swap out a driver backend on different OSes, and to export more symbols when testing. Would it make sense to have a haskell version of CPP that provides only these features (e.g. just #ifdef, #else, #endif, and #define) and leaves out the problematic C comments and backslash expectations? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -- Felipe. -- Felipe. ___ 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
Re: [Haskell-cafe] build failure on Hackage
* Brian Lewis br...@lorf.org [2013-07-13 14:30:01-0500] I maintain a library that, on Linux, needs libXxf86vm to build. The server where Hackage runs doesn't have that library, so the build fails. I think this is reasonable -- that box can't possibly have all the libraries various packages might need. But the build failure seems to cause the Haddock docs to not be generated. Why? This is a consequence of how haddock works. It uses GHC API, which has to compile modules before haddock can process them. My understanding is, if someone specifies my library as a build dependency, my library's build failure will also cause the docs for their package not to be built. I think my library will kill the Hackage Haddock docs for any other package that depends on it, due to a build error that's not even meaningful. What can I do? 1. Why exactly does haddock fail? IINM, the absence of library itself (i.e. an .a or .so file) shouldn't be a problem, as haddock doesn't do linking. If the problem is due to an absent include file, perhaps you can bundle it with your package for the sake of generating documentation? To generate documentation without linking, do cabal configure cabal haddock instead of cabal install 2. You can use standalone-haddock to generate the documentation on a system where the library is installed and then upload it to your own web host. Unfortunately, this won't solve the problem with reverse deps (but they could do the same). 3. If we ever switch to Hackage 2, this problem should be solved by user-uploadable docs. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] build failure on Hackage
* Brian Lewis br...@lorf.org [2013-07-13 15:44:58-0500] On 2013.07.13, at 23:15, Roman Cheplyaka wrote: 1. Why exactly does haddock fail? I think it never actually tries to build the Haddock docs for the actual package of interest because its dependencies failed to build. Here's the GLFW-b build log: http://hackage.haskell.org/packages/archive/GLFW-b/1.0.0/logs/failure/ghc-7.6 ... Running Haddock for bindings-DSL-1.0.16... ... Running Haddock for th-lift-0.5.5... ... * Missing C library: Xxf86vm These messages are from the build of bindings-GLFW, a dependency of GLFW-b. Due to the missing library, bindings-GLFW's build fails. So GLFW-b's does too. I guess I think the build failure should be noted, but that Hackage should go on and build the docs anyway. Ah, yes. This may be a bit more complicated than it seems, due to the way Cabal works. Let's say you've built the docs for this library. Now you have to install it, so that its reverse dependencies can reference it. Installation involves registering the package, so that Cabal can later see which packages are installed. Here's the catch: package databases are maintained by compilers, not by Cabal. In the common case this means GHC. (Unfortunately, haddock is not a separate compiler, which would be a more proper solution.) So we must register the package with GHC. But then we cannot distinguish between real and docs-only packages. Cabal and GHC would expect package to be installed, and would happily attempt to build other packages against it, and fail miserably. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Quick-check: how to generate arbitrary complex data?
* martin martin.drautzb...@web.de [2013-07-12 08:33:54+0200] Hello all, I have a type (Mail) which consists of hash and a list, where the hash keeps some redundant data of the list for faster access. I can add and remove elements to values of this type using custom functions, called push and pop. Now I wanted to write some quick checks, but I have no clue how to generate arbitrary values of this type. It will certainly no suffice to write arbitrary instances for the underlying types (Int and Char), because the hash and the list need to be synchronized. Currently Mail it is only a type synonym. I suppose as a prerequisite I need to wrap it into a type constructor. But then what? QuickCheck's Gen is a functor. So you can generate a list, and then use fmap to add a hash to it. instance Arbitrary HashedList where arbitrary = addHashToList $ arbitrary Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Deriving with generics without values
Well, in your case, you need not 'from', but 'to', in order to convert from a generic representation to yours. Take a look at how a similar task is done in SmallCheck: https://github.com/feuerbach/smallcheck/blob/master/Test/SmallCheck/Series.hs#L180 https://github.com/feuerbach/smallcheck/blob/master/Test/SmallCheck/Series.hs#L352 Roman * JP Moresmau jpmores...@gmail.com [2013-07-12 10:45:39+0200] Hello all, My problem is the following: I have my own data types, and I'd like to derive automatically instances of some type class from them. I've started looking at GHC.Generics, which offer tools to do exactly that. However, some functions of my typeclass do not take my data type as a parameter, but as a result. Basically: class MyClass where fromString :: String - a data MyData=MkMyData { myField ::Int } deriving (Generic) and I want to automatically generate the instance instance MyClass MyData, using default methods, etc. The GHC Generic class does say that it uses a from function that convert from the datatype to its representation: from :: a - Rephttp://www.haskell.org/ghc/docs/7.4.1/html/libraries/ghc-prim-0.2.0.0/GHC-Generics.html#t:Rep a xfrom :: a - Rephttp://www.haskell.org/ghc/docs/7.4.1/html/libraries/ghc-prim-0.2.0.0/GHC-Generics.html#t:Rep a x But I don't have a a to start from! I see from the related papers that the automatically generated code from from actually does pattern matches on constructors, so I need a value, undefined won't work. However I see the GHC.Generics also provide :+: (Sums: encode choice between constructors). If I have to provide an value, then the choice between constructor has been done! The examples about generics on http://www.haskell.org/haskellwiki/GHC.Generics do provide an example of defining the instance for :+: but I don't understand how we can get there. If I have a class method that takes a value as a parameter, and I pass undefined to it, the code will crash, since it can't pattern match on undefined. Can somebody shed some light on this? Am I using the wrong tool for the job? How can I achieve what I want? I want the full type representation with sums, but without a value to start from. Thanks a million! JP -- JP Moresmau http://jpmoresmau.blogspot.com/ ___ 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
Re: [Haskell-cafe] getting haddock to cooperate with cpp
* Evan Laforge qdun...@gmail.com [2013-07-12 14:25:00-0400] So haddock ignores {-# LANGUAGE CPP #-}, which makes it crash on any file that uses it. I'm pretty sure it's not true in general. If you click on the Source link at this haddock page: http://hackage.haskell.org/packages/archive/smallcheck/0.6.2/doc/html/Test-SmallCheck-Series.html you'll see that CPP is used there. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Comparing functions
* Vlatko Basic vlatko.ba...@gmail.com [2013-07-11 19:33:38+0200] Hello Cafe, I have data CmpFunction a = CF (a - a - Bool) that contains comparing functions, like ==, , ..., and I'm trying to declare the Show instance for it like this instance Show (CmpFunction a) where show (CF (==)) = ==-- no good show f = case f of-- no good also CBF (==) - == _ - Other but compiler complains for both with This binding for `==' shadows the existing binding imported from `Prelude' at src/Main.hs:6:8-11 (and originally defined in `ghc-prim:GHC.Classes') Is it possible at all to compare two functions or how to solve this problem, to show some string for a specific function? Depending on why you need that... {-# LANGUAGE FlexibleContexts, UndecidableInstances, FlexibleInstances #-} import Test.SmallCheck import Test.SmallCheck.Series import Test.SmallCheck.Drivers import Control.Monad.Identity import Data.Maybe data CmpFunction a = CF (a - a - Bool) feq :: (Show a, Serial Identity a) = CmpFunction a - CmpFunction a - Bool feq (CF f1) (CF f2) = isNothing $ runIdentity $ smallCheckM 10 (\x1 x2 - f1 x1 x2 == f2 x1 x2) instance Show (CmpFunction Integer) where show f | f `feq` CF (==) = == | f `feq` CF (/=) = /= | f `feq` CF () = | f `feq` CF (=) = = | otherwise = Unknown function This uses SmallCheck to figure out, with some degree of certainty, whether two functions are equal. Of course, Rice's theorem still holds, and the above instance is easy to fool, but it still might be useful in some cases. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Parsec error message not making any sense
Please check your code. I had two problems with it: mixed tabs and spaces, and undefined 'quotedChar'. After defining quotedChar = anyChar, I get a different error message from yours: *Main parseFromFile textgridfile testdata.TextGrid Left testdata.TextGrid (line 137, column 1): unexpected end of input expecting quote at end of cell Roman * Fredrik Karlsson dargo...@gmail.com [2013-07-09 08:07:24+0200] Hi Roman, I'm using parsec-3.1.3 I put the code in a gist here - sorry about that. https://gist.github.com/dargosch/5955045 Fredrik On Tue, Jul 9, 2013 at 12:08 AM, Roman Cheplyaka r...@ro-che.info wrote: Hi Fredrik, First, do you use the latest parsec version (3.1.3)? If not, can you try the same with 3.1.3? Second, please upload your code to hpaste.org or a similar service and give us the link. It's not much fun to extract code from an html email. Roman * Fredrik Karlsson dargo...@gmail.com [2013-07-08 23:54:17+0200] Dear list, I have a Parsec parser that fails and gives the following error message: *Main parseFromFile textgridfile testFile Left /Users/frkkan96/Documents/src/ume/umecore/testing/testdata/testdata.TextGrid (line 35, column 5): unexpected t expecting intervals [ Now, this is perfectly understandable, but line 35, col 5 in the file being parsed looks like the supplies image - there is no 't' there. Any ideas on what is going on? The parser I am using is: data VariableLine = VariableLine String String deriving Show data TierType = IntervalTier | PointTier deriving Show data Tier = Tier String deriving Show data LabelFile = LabelFile Double Double deriving Show data Label = Label String TierType Double Double String deriving Show haskelldef = makeTokenParser haskellDef textgridfile :: Parser (LabelFile, [[Label]]) textgridfile = do h - header ll - many1 tier return $ (h,ll) header :: Parser LabelFile header = do string headTS1 start - try (float haskelldef) | (fmap fromInteger $ integer haskelldef ) string xmax = end - try (float haskelldef) | (fmap fromInteger $ integer haskelldef ) string tiers? exists \n string size = integer haskelldef string item []: whiteSpace haskelldef return $ LabelFile start end tier :: Parser [Label] tier = do whiteSpace haskelldef string item [ integer haskelldef string ]: whiteSpace haskelldef try (string class = \IntervalTier\) | string class = \TextTier\ whiteSpace haskelldef string name = char '' name - many quotedChar char '' ? quote at end of cell whiteSpace haskelldef string xmin = try (float haskelldef) | (fmap fromInteger $ integer haskelldef ) whiteSpace haskelldef string xmax = try (float haskelldef) | (fmap fromInteger $ integer haskelldef ) string intervals: size = | string points: size = integer haskelldef whiteSpace haskelldef labelList - many1 (interval name) return $ labelList interval :: String - Parser Label interval tierName = do whiteSpace haskelldef string intervals [ integer haskelldef string ]: whiteSpace haskelldef string xmin = start - try (float haskelldef) | (fmap fromInteger $ integer haskelldef ) whiteSpace haskelldef string xmax = end - try (float haskelldef) | (fmap fromInteger $ integer haskelldef ) whiteSpace haskelldef string text = char '' text - many quotedChar char '' ? quote at end of cell return $ Label tierName IntervalTier start end text which fails on the attached input file. I can't see how 't' is found?? What am I doing wrong? /Fredrik -- Life is like a trumpet - if you don't put anything into it, you don't get anything out of it. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -- Life is like a trumpet - if you don't put anything into it, you don't get anything out of it. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Understanding version differences
The compiler defaults the kind of 'quality' (i.e. the first argument of QUALITIES) to *, not being able to infer it from the class definition itself (and other definitions that it references). Since you want it to have kind * - *, you should enable KindSignatures and add an annotation, or otherwise disambiguate the kind. This behaviour follows the Haskell Report. The change from previous versions of GHC is documented here: http://www.haskell.org/ghc/docs/7.4.1/html/users_guide/release-7-4-1.html#id3015054 Roman * Patrick Browne patrick.bro...@dit.ie [2013-07-09 12:45:19+0100] Hi, The code [1] below compiles and runs with GHCi version 7.0.4. I get one warning and an error message with GHCi version 7.6.1. 1) Warning -XDatatypeContexts is deprecated. Unless there are propagation effects, this is well explained. 2) foom-1.hs:65:15: `quality' is applied to too many type arguments In the type `quality entity - agent - IO Observation' In the class declaration for `OBSERVERS' Failed, modules loaded: none. I do not understand the error message from 7.6.1. I am not too interested actually fixing it, I just want to understand it. Thanks, Pat [1]The code is from: A Functional Ontology of Observation and Measurement Werner Kuhn {-# LANGUAGE DatatypeContexts,MultiParamTypeClasses #-} module ENDURANTS where import System.Time type Id = String type Position = Integer type Moisture = Float type Celsius = String type Heat = Float data WeatherStation = WeatherStation Id Position deriving Show data Value = Boolean Bool | Count Int | Measure Float | Category String deriving Show data Observation = Observation Value Position ClockTime deriving Show data AmountOfAir = AmountOfAir Heat Moisture deriving Show muensterAir = AmountOfAir 10.0 70.0 class ENDURANTS endurant where -- must add instances all down the hierarchy for each instance instance ENDURANTS WeatherStation where instance ENDURANTS AmountOfAir where class ENDURANTS physicalEndurant = PHYSICAL_ENDURANTS physicalEndurant where instance PHYSICAL_ENDURANTS WeatherStation where instance PHYSICAL_ENDURANTS AmountOfAir where class PHYSICAL_ENDURANTS amountOfMatter = AMOUNTS_OF_MATTER amountOfMatter where instance AMOUNTS_OF_MATTER WeatherStation where class PHYSICAL_ENDURANTS physicalObject = PHYSICAL_OBJECTS physicalObject where instance PHYSICAL_OBJECTS WeatherStation where class PHYSICAL_OBJECTS apo = APOS apo where getPosition :: apo - Position instance APOS WeatherStation where getPosition (WeatherStation iD pos) = pos + 10 -- a data type declaration and data type constructor. data PHYSICAL_ENDURANTS physicalEndurant = Temperature physicalEndurant = Temperature physicalEndurant deriving Show -- Qualities the class of all quality types (= properties) is a constructor class -- its constructors can be applied to endurants, perdurants, qualities or abstracts class QUALITIES quality entity instance QUALITIES Temperature AmountOfAir class (APOS agent, QUALITIES quality entity) = OBSERVERS agent quality entity where observe :: quality entity - agent - IO Observation express :: quality entity - agent - Value observe quale agent = do clockTime - getClockTime return (Observation (express quale agent) (getPosition agent) clockTime) instance OBSERVERS WeatherStation Temperature AmountOfAir where express (Temperature (AmountOfAir heat moisture)) weatherStation = Measure heat {- -- running the following express (Temperature (AmountOfAir 40 20)) (WeatherStation rr 6) -- Gives Measure 40.0 Measure 40.0 -- We can get the type: Value :t express (Temperature (AmountOfAir 40 20)) (WeatherStation rr 6) -} Tá an teachtaireacht seo scanta ó thaobh ábhar agus víreas ag Seirbhís Scanta Ríomhphost de chuid Seirbhísí Faisnéise, ITBÁC agus meastar í a bheith slán. [1]http://www.dit.ie This message has been scanned for content and viruses by the DIT Information Services E-Mail Scanning Service, and is believed to be clean. [2]http://www.dit.ie References 1. http://www.dit.ie/ 2. http://www.dit.ie/ ___ 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
Re: [Haskell-cafe] GHC bug? Let with guards loops
As Dan said, this behaviour is correct. The confusing thing here is that in case expressions guards are attached to the patterns (i.e. to the lhs), while in let expressions they are attached to the rhs. So, despite the common Just x | x 0 part, your examples mean rather different things. Here's the translation of 'loops' according to the Report: loops = let Just x = case () of () | x 0 - Just 1 in x Here it's obvious that 'x' is used in the rhs of its own definition. Roman * Andreas Abel andreas.a...@ifi.lmu.de [2013-07-09 16:42:00+0200] Hi, is this a known bug or feature of GHC (7.4.1, 7.6.3)?: I got a looping behavior in one of my programs and could not explain why. When I rewrote an irrefutable let with guards to use a case instead, the loop disappeared. Cut-down: works = case Just 1 of { Just x | x 0 - x } loops = let Just x | x 0 = Just 1 in x works returns 1, loops loops. If x is unused on the rhs, the non-termination disappears. works' = let Just x | x 0 = Just 1 in 42 Is this intended by the Haskell semantics or is this a bug? I would have assumed that non-recursive let and single-branch case are interchangeable, but apparently, not... Cheers, Andreas -- Andreas AbelDu bist der geliebte Mensch. Theoretical Computer Science, University of Munich Oettingenstr. 67, D-80538 Munich, GERMANY andreas.a...@ifi.lmu.de http://www2.tcs.ifi.lmu.de/~abel/ ___ 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
Re: [Haskell-cafe] Parsec error message not making any sense
Hi Fredrik, First, do you use the latest parsec version (3.1.3)? If not, can you try the same with 3.1.3? Second, please upload your code to hpaste.org or a similar service and give us the link. It's not much fun to extract code from an html email. Roman * Fredrik Karlsson dargo...@gmail.com [2013-07-08 23:54:17+0200] Dear list, I have a Parsec parser that fails and gives the following error message: *Main parseFromFile textgridfile testFile Left /Users/frkkan96/Documents/src/ume/umecore/testing/testdata/testdata.TextGrid (line 35, column 5): unexpected t expecting intervals [ Now, this is perfectly understandable, but line 35, col 5 in the file being parsed looks like the supplies image - there is no 't' there. Any ideas on what is going on? The parser I am using is: data VariableLine = VariableLine String String deriving Show data TierType = IntervalTier | PointTier deriving Show data Tier = Tier String deriving Show data LabelFile = LabelFile Double Double deriving Show data Label = Label String TierType Double Double String deriving Show haskelldef = makeTokenParser haskellDef textgridfile :: Parser (LabelFile, [[Label]]) textgridfile = do h - header ll - many1 tier return $ (h,ll) header :: Parser LabelFile header = do string headTS1 start - try (float haskelldef) | (fmap fromInteger $ integer haskelldef ) string xmax = end - try (float haskelldef) | (fmap fromInteger $ integer haskelldef ) string tiers? exists \n string size = integer haskelldef string item []: whiteSpace haskelldef return $ LabelFile start end tier :: Parser [Label] tier = do whiteSpace haskelldef string item [ integer haskelldef string ]: whiteSpace haskelldef try (string class = \IntervalTier\) | string class = \TextTier\ whiteSpace haskelldef string name = char '' name - many quotedChar char '' ? quote at end of cell whiteSpace haskelldef string xmin = try (float haskelldef) | (fmap fromInteger $ integer haskelldef ) whiteSpace haskelldef string xmax = try (float haskelldef) | (fmap fromInteger $ integer haskelldef ) string intervals: size = | string points: size = integer haskelldef whiteSpace haskelldef labelList - many1 (interval name) return $ labelList interval :: String - Parser Label interval tierName = do whiteSpace haskelldef string intervals [ integer haskelldef string ]: whiteSpace haskelldef string xmin = start - try (float haskelldef) | (fmap fromInteger $ integer haskelldef ) whiteSpace haskelldef string xmax = end - try (float haskelldef) | (fmap fromInteger $ integer haskelldef ) whiteSpace haskelldef string text = char '' text - many quotedChar char '' ? quote at end of cell return $ Label tierName IntervalTier start end text which fails on the attached input file. I can't see how 't' is found?? What am I doing wrong? /Fredrik -- Life is like a trumpet - if you don't put anything into it, you don't get anything out of it. ___ 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
Re: [Haskell-cafe] Catch multiple exceptions using 'Control.Exception'
* Nikita Karetnikov nik...@karetnikov.org [2013-07-06 20:12:58+0400] Here you go: import Control.Exception import Data.Typeable syncExceptions :: SomeException - Maybe SomeException syncExceptions e | Just _ - cast e :: Maybe AsyncException = Nothing | otherwise = Just e Thanks, but it doesn't work as expected: *Main syncExceptions $ toException StackOverflow Just stack overflow It should return 'Nothing' instead: *Main cast $ toException StackOverflow :: Maybe AsyncException Nothing I've received another solution, and it works fine. I also have other questions (see below). Ah yes, fromException is the right function, of course. Sorry for confusion. Could anyone elaborate on the following terms: a closed sum type and an open existential type? What is the meaning of the words open and closed? Is there an open sum type or a closed existential type? Closed means that the set of possible constructors is, well, closed — you have to decide on it when you're defining your type and you can't later add anything to it. Open means the opposite. A classical example of an open type is any type in an OO language with subtyping, such as Java. You can extend the Object type without limitations, without modifying the Object type itself. Exceptions are very similar in this regard — you can add new classes of exceptions without a need to mess with the Control.Exception module, just by defining a couple of methods. For more details you may want to read An Extensible Dynamically-Typed Hierarchy of Exceptions. Also, I thought that a sum type [1] should only have two value constructors: ... [1] http://chris-taylor.github.io/blog/2013/02/10/the-algebra-of-algebraic-data-types/ That's just different terminology. When talking about Haskell, we usually call any algebraic type with multiple constructors a sum type. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Catch multiple exceptions using 'Control.Exception'
* Nikita Karetnikov nik...@karetnikov.org [2013-07-03 15:50:16+0400] Perhaps you can use `catches` [0]? Maybe, but my idea is to replace 'syncExceptions' with a similar function. Otherwise, it'll be necessary to change (at least) all functions that use 'syncExceptions'. I'd like to avoid that. Here you go: import Control.Exception import Data.Typeable syncExceptions :: SomeException - Maybe SomeException syncExceptions e | Just _ - cast e :: Maybe AsyncException = Nothing | otherwise = Just e Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANNOUNCE: haskell-names-0.1
* Andrew Cowie and...@operationaldynamics.com [2013-06-21 16:12:55+1000] On Thu, 2013-06-20 at 18:13 +0300, Roman Cheplyaka wrote: Namely, it can do the following: * for a module, compute its interface, i.e. the set of entities exported by the module, together with their original names. * for each name in the module, figure out what it refers to — whether it's bound locally (say, by a where clause) or globally (and then give its origin). Is this a step toward being able to automatically derive an API version number [in the SO version sense of the word; ie, has a change happened requiring a version bump?] Yes, this sounds like a good weekend project for someone interested. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] ANNOUNCE: haskell-names-0.1
I am pleased to announce the first public release of haskell-names, a name resolution library for haskell-src-exts AST. Namely, it can do the following: * for a module, compute its interface, i.e. the set of entities exported by the module, together with their original names. * for each name in the module, figure out what it refers to — whether it's bound locally (say, by a where clause) or globally (and then give its origin). Thanks to haskell-packages, this library is fully integrated with Cabal, so that you can easily generate name interfaces for any Cabalized package. See more details in the README: http://documentup.com/haskell-suite/haskell-names This library is based on the code written by Lennart Augustsson in 2010. Little of that code survived, but nevertheless it's been a great help. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Testing invasive proposals with Hackager
To make it clear, it's not yet written, although I'll start spending more time on it soon. So far I've been working on the haskell-suite set of libraries that are necessary to implement HasFix. (https://github.com/haskell-suite) Roman * AlanKim Zimmerman alan.z...@gmail.com [2013-06-13 20:45:43+0200] Roman Cheplyaka has written a tool called HasFix for updating source based on new versions of libraries. The presentation on it is here http://ro-che.info/docs/ and the code is at https://github.com/feuerbach/hasfix Perhaps it could be pressed into use for automatic update of historical code? Alan On Thu, Jun 13, 2013 at 6:30 PM, Maksymilian Owsianny maksymilian.owsia...@gmail.com wrote: I was thinking about something similar some time ago, but not just testing but also fixing things automatically. Taking for example Semigroup = Monoid this would break in places where you have instance for Monoid but don't have instance for Semigroup. But if you have instance for Monoid making instance for Semigroup is straightforward: instance Semigroup TypeYouAreFixing where () = copy code from mappend for that type I'm still kind of new to Haskell, so I'm not sure how hard such, TemplateHaskell-like automagic migration tool, would be to make, but I feel like such a tool would be of incredible importance for the community. Because otherwise, without such thing, there are usually two ways a language can evolve: 1. Caring for backwards compatibility, and accumulating mistakes like that over time, and becoming more and more like crap. 2. Making fixes that break everyones code, and because of that being ignored by the industry. I like Haskell because it usually takes the second route, but as community grows it will be less and less the case. With such a tool you could have best of both worlds. Though I assume that somebody already thought of that and come to the conclusion that in general case you cannot make such tool because Gödel is a bastard that breaks everyones toys, or something along this lines. On Thu, Jun 13, 2013 at 12:54 PM, Niklas Hambüchen m...@nh2.me wrote: On 13/06/13 18:36, Vo Minh Thu wrote: For example, here is a run with GHC, no special options and using 4 threads (note that this generally takes a long time, i.e. a few days): My builds finished in 10 hours on an i7. ___ 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 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
Re: [Haskell-cafe] Haskell Platform 2013.2.0.0 64bit.pkg
* Richard A. O'Keefe o...@cs.otago.ac.nz [2013-06-13 17:37:57+1200] Today I cleared out everything, using uninstall-hs and rm -rf ~/.cabal ~/Library/Haskell I downloaded Haskell Platform 2013.2.0.0 64bit.pkg and installed it. I was unsuccessful in installing the packages I wanted using cabal install, which suggested running ghc-pkg check. So I cleared out everything again and reinstalled the HP. In the admin account, ghc-pkg check says Warning: haddock-interfaces: /Library/Haskell/ghc-7.6.3/lib/haskell-platform-2013.2.0.0/ doc/html/haskell-platform.haddock doesn't exist or isn't a file Warning: haddock-html: /Library/Haskell/ghc-7.6.3/lib/haskell-platform-2013.2.0.0/ doc/html doesn't exist or isn't a directory This is harmless (but should be fixed). Do you need help with your original problem? If so, please give us more details. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANNOUNCE: standalone-haddock-1.0
* Johannes Waldmann waldm...@imn.htwk-leipzig.de [2013-06-08 12:45:17+] Roman Cheplyaka roma at ro-che.info writes: http://feuerbach.github.io/standalone-haddock/ yes, awesome! I took me a while to figure out I need to add --package-db $HOME/.ghc/x86_64-linux-7.6.3/package.conf.d This is strange, it should look there by default. um, where's --hyperlink-source ? It's not implemented yet. Patches are welcome :) Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANNOUNCE: standalone-haddock-1.0
* Mateusz Kowalczyk fuuze...@fuuzetsu.co.uk [2013-06-08 16:16:54+0100] On 07/06/13 13:15, Roman Cheplyaka wrote: I am happy to announce the first release of standalone-haddock. http://feuerbach.github.io/standalone-haddock/ standalone-haddock generates standalone haddock Haskell documentation. When you simply run `cabal haddock`, the resulting HTML documentation contains hyperlinks to other packages on your system. As a result, you cannot publish it on the internet (well, you can, but the links will be broken). standalone-haddock takes several packages for which you want to publish documentation. It generates documentation for them with proper links: * links to identifiers inside this package set are relative * links to identifiers from external packages lead to hackage Thus the resulting directory with HTML is relocatable and publishable. **TL;DR**: it just works. See the [haskell-suite][] documentation for an example output. [haskell-suite]: http://haskell-suite.github.io/docs [snip] I could have really used this about 2 days ago. Oh well. Do you have any idea about how well this will work on all of the GHC source? That is, are there any known issues that would prevent it from working or require a special setup? I imagine it would not be trivial, due to GHC's complicated build system. There's also a known issue that preprocessing doesn't happen (e.g. for alex and happy files) — I hope to fix that soon. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] ANNOUNCE: standalone-haddock-1.1
* Roman Cheplyaka r...@ro-che.info [2013-06-08 19:25:12+0300] There's also a known issue that preprocessing doesn't happen (e.g. for alex and happy files) — I hope to fix that soon. I've just released standalone-haddock-1.1 which fixes the above issue and also adds --hyperlink-source (the latter was kindly contributed by Joey Adams). For some reason my uploads don't finish and the hackage index doesn't get updated. You can still download the source tarball from hackage or github. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] ANNOUNCE: standalone-haddock-1.0
I am happy to announce the first release of standalone-haddock. http://feuerbach.github.io/standalone-haddock/ standalone-haddock generates standalone haddock Haskell documentation. When you simply run `cabal haddock`, the resulting HTML documentation contains hyperlinks to other packages on your system. As a result, you cannot publish it on the internet (well, you can, but the links will be broken). standalone-haddock takes several packages for which you want to publish documentation. It generates documentation for them with proper links: * links to identifiers inside this package set are relative * links to identifiers from external packages lead to hackage Thus the resulting directory with HTML is relocatable and publishable. **TL;DR**: it just works. See the [haskell-suite][] documentation for an example output. [haskell-suite]: http://haskell-suite.github.io/docs Usage - Usage: standalone-haddock [--package-db DB-PATH] -o OUTPUT-PATH [PACKAGE-PATH] Available options: -h,--helpShow this help text --package-db DB-PATH Additional package database -o OUTPUT-PATH Directory where html files will be placed `PACKAGE-PATH` is the path to the (unpacked) package — i.e. a directory with a `.cabal` file. For example: standalone-haddock -o doc haskell-names haskell-packages haskell-src-exts hse-cpp cabal/Cabal **NOTE**: dependencies of every package need to be already installed in the system with documentation (even those dependencies that themselves belong to the current package set). If they are installed in a non-standard package database (e.g. if you use sandboxes), use the `--package-db` option. Cabal dependency The program only builds with (unreleased) Cabal 1.17 which you can get from [github](https://github.com/haskell/cabal). I spent some time trying to make it compatible with Cabal 1.16 (see [Cabal-1.16][] branch), but the API seems to have changed too much. If you seriously care about this, feel free to send a patch, but it's really easier just to install Cabal HEAD. [Cabal-1.16]: https://github.com/feuerbach/standalone-haddock/tree/Cabal-1.16 Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Question about Newtype op() function arguments.
* David Banas capn.fre...@gmail.com [2013-06-07 07:08:19-0700] Hi All, Referring to the following, which is taken from the *Control.Newtype *documentation page: op :: Newtypehttp://hackage.haskell.org/packages/archive/newtype/0.2/doc/html/Control-Newtype.html#t:Newtype n o = (o - n) - n - oSourcehttp://hackage.haskell.org/packages/archive/newtype/0.2/doc/html/src/Control-Newtype.html#op This function serves two purposes: 1. Giving you the unpack of a newtype without you needing to remember the name. 2. Showing that the first parameter is *completely ignored* on the value level, meaning the only reason you pass in the constructor is to provide type information. Typeclasses sure are neat. As point #2, above, emphasizes, the only purpose for the first argument to the function (i.e. - the constructor (o - n)) is to specify the type of 'n'. However, being a *newtype*, 'n' can have only one constructor. So, why is it necessary to pass in the constructor to this function, when we're already passing in 'n'? Hi David, Note that that argument is in fact not necessary — 'op' without its first argument is exactly 'unpack'. I imagine that 'op' may be useful if you need to disambiguate the instance in an otherwise ambiguous context. One way to do this is, of course, to provide an explicit type signature, but passing a constructor is another, and rather elegant, way to achieve that. I am not a heavy user of the newtype package, so I can't say how often this situation occurs in practice. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Why isn't hsc2hs functionality provided by ghc?
* Jason Dagit dag...@gmail.com [2013-06-04 21:00:25-0700] My preferred solution would be to have ghc/ghci automatically run hsc2hs (support c2hs also?) when necessary. But so long as it's handled automatically, I wouldn't be particularly bothered by the implementation. How about having a `ghci` command for cabal? Or does the automatic requirement really need to be part of ghc to work the way you want? (BTW, cabal-dev does have a `ghci` command, but I haven't tested to see if it does the hsc - hs conversion.) I don't think cabal can provide that. Let's say you're inside a 'cabal ghci' session. If you modify the hsc file and reload it in ghci, you'd expect to load the updated version — yet cabal hasn't even been called since 'cabal ghci', and have had no chance to re-generate the hs file. To answer the subject question — hsc2hs is not a single preprocessor available. There are also c2hs and greencard, and maybe something else. It is (or, at least, was) not clear which one should be generally preferred. Perhaps by now hsc2hs is a clear winner — I don't know. Another option is to add a generic preprocessor option to GHC, something like -pgmX cmd. Then, for hsc2hs one would write something like {-# OPTIONS_GHC -pgmX hsc2hs #-} This is a better option, IMO. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Typeable typeclass and type-level naturals
* TP paratribulati...@free.fr [2013-06-05 00:37:36+0200] Roman Cheplyaka wrote: Try adding deriving instance Typeable 'Zero deriving instance Typeable a = Typeable ('Succ a) to your module. (I haven't tested it — you might need to tweak it a bit.) Thanks Roman. Unfortunately, I already tried that (without the constraint Typeable a =, what a fool), but it did not work. The error is the same with the constraint: Derived typeable instance must be of form (Typeable 'Succ) In the stand-alone deriving instance for ‛Typeable a = Typeable (Succ a)’ What is the problem? Oh, it should probably be simply deriving instance Typeable 'Zero deriving instance Typeable 'Succ Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Why isn't hsc2hs functionality provided by ghc?
* Ivan Lazar Miljenovic ivan.miljeno...@gmail.com [2013-06-05 17:47:40+1000] On 5 June 2013 17:34, Roman Cheplyaka r...@ro-che.info wrote: * Jason Dagit dag...@gmail.com [2013-06-04 21:00:25-0700] My preferred solution would be to have ghc/ghci automatically run hsc2hs (support c2hs also?) when necessary. But so long as it's handled automatically, I wouldn't be particularly bothered by the implementation. How about having a `ghci` command for cabal? Or does the automatic requirement really need to be part of ghc to work the way you want? (BTW, cabal-dev does have a `ghci` command, but I haven't tested to see if it does the hsc - hs conversion.) I don't think cabal can provide that. Let's say you're inside a 'cabal ghci' session. If you modify the hsc file and reload it in ghci, you'd expect to load the updated version — yet cabal hasn't even been called since 'cabal ghci', and have had no chance to re-generate the hs file. To answer the subject question — hsc2hs is not a single preprocessor available. There are also c2hs and greencard, and maybe something else. It is (or, at least, was) not clear which one should be generally preferred. Perhaps by now hsc2hs is a clear winner — I don't know. Another option is to add a generic preprocessor option to GHC, something like -pgmX cmd. Then, for hsc2hs one would write something like {-# OPTIONS_GHC -pgmX hsc2hs #-} Isn't this what -pgmF is for?http://www.haskell.org/ghc/docs/7.6.1/html/users_guide/options-phases.html#replacing-phases {-# OPTIONS_GHC -F -pgmF hsc2hs #-} Indeed! I should've read the whole section. Problem solved, then? Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Typeable typeclass and type-level naturals
Try adding deriving instance Typeable 'Zero deriving instance Typeable a = Typeable ('Succ a) to your module. (I haven't tested it — you might need to tweak it a bit.) Roman * TP paratribulati...@free.fr [2013-06-02 18:08:02+0200] Hi all, I try to play with the Typeable typeclass, and I have some difficulties to make it work in this simple case where I use type-level naturals: - {-# LANGUAGE GADTs #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE StandaloneDeriving #-} import Data.Typeable data Nat = Zero | Succ Nat deriving ( Show, Eq, Ord, Typeable ) data Box where Box :: (Typeable s, Show s, Eq s) = s - Box deriving Typeable data Proxy a = P deriving Typeable deriving instance Show Box instance Eq Box where (Box s1) == (Box s2) = Just s1 == cast s2 main = do let one = undefined :: Main.Proxy ('Succ 'Zero) let foo = Box one print foo - I obtain: - No instance for (Typeable Nat 'Zero) arising from a use of ‛Box’ In the expression: Box one In an equation for ‛foo’: foo = Box one In the expression: do { let one = ...; let foo = Box one; print foo } - Note that it is necessary to use the HEAD version of GHC to obtain this message (I use version 7.7.20130525); with GHC 7.6.2, the message is different because recent improvements in Typeable are not present (1). What is the problem? I've tried different things without success. Tell me if the beginners diffusion list is more suitable than Haskell- Cafe. Thanks, TP (1): http://hauptwerk.blogspot.fr/2012/11/coming-soon-in-ghc-head-poly-kinded.html ___ 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
Re: [Haskell-cafe] Stream instance for Parsec + conduits
Hi Phil, Sorry for the late answer — somehow I missed your email when it was originally posted. Parsec wasn't designed for incremental input, and adding it without modifying the internals would be tricky. The problem with your code is this: at the branching point, Parsec remembers the current state of the stream — i.e. . Then it runs the first branch, and, after that has failed, the second branch — both with the same state of the stream, . The first branch, when being run, grabs the g from conduit. The second branch, since it was passed , also asks conduit for the input. Alas, conduit has already given away its only chunk of data. It has no idea that this is a different branch which is unaware of the previous events. One way around this is to have a wrapper around the conduit monad — a simple StateT should suffice. It must cache the whole input. The stream itself (i.e. your StreamSource) can be simply an Int which denotes the position in the stream. Your monad then can supply the data requested by its position, without losing data when switching branches. A drawback of this is that you don't know how long to hold that data, and thus have a memory leak. Attoparsec has it, too, by the way, but it is not related to being incremental. It is possible to alter Parsec so that you have both incremental input support and the ability to release parts of the input that are no longer needed. Roman * Phil Scott m...@philscotted.com [2013-05-09 18:57:51+0100] Hi all. I would like to have a Parsec Stream instance for Data.Text streams in yesod's ConduitM. So far, I have this: hpaste.org/87599 The idea is that because Yesod's conduits will be chunking values in Data.Text, I should have a wrapper StreamSource to cache chunked values. For some reason, the test parser fails, saying: [Left Blah (line 1, column 1): unexpected g expecting h or g] Any ideas? Cheers! Phil ___ 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
Re: [Haskell-cafe] Design of extremely usable programming language libraries
* Andrey Chudnov achud...@gmail.com [2013-05-28 16:36:14-0400] * Does any generic traversal/transformation (uniplate-style) library support GADTs? Any syb-style library works with GADTs, by the virtue of dealing with value representations instead of type representations. * What is the best choice, performance- and memory-wise, for a parser combinator library with support for arbitrary look-ahead? Parsec is considered slow by some [1], but is it only in comparison with attoparsec (which, unfortunately, doesn't support arbitrary look-ahead)? Is there any parser library that performs better than Parsec while still supporting arbitrary look-ahead. Not sure what you mean here — attoparsec does support unlimited lookahead, in the sense that a parser may fail arbitrarily late in the input stream, and backtrack to any previous state. Although attoparsec is a poor choice for programming language parsing, primarily because of the error messages. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Design of extremely usable programming language libraries
Unfortunately you can only do traversals, not unfolds, with GADTs. That's because in an unfold, the return type is determined by the value itself and can vary among the produced results, whereas in a traversal it is determined by the input type. This means also that you cannot simply derive Data, because the derived instance will contain a gunfold function, which then will fail to typecheck. You can copy-paste the generated instance (-ddump-deriv) and simply remove the code for gunfold (or write your own deriver). The following compiles for me: https://gist.github.com/feuerbach/5668198 Roman * Andrey Chudnov achud...@gmail.com [2013-05-28 17:29:10-0400] Thanks for a prompt reply, Roman. On 05/28/2013 04:52 PM, Roman Cheplyaka wrote: Any syb-style library works with GADTs, by the virtue of dealing with value representations instead of type representations. I tried to use syb, but the following code fails to typecheck for me. What am I doing wrong? {-# LANGUAGE GADTs, EmptyDataDecls, MultiParamTypeClasses, TypeFamilies #-} {-# LANGUAGE DeriveDataTypeable, StandaloneDeriving #-} data HasHoles data Complete deriving instance Typeable HasHoles deriving instance Data HasHoles deriving instance Typeable Complete deriving instance Data Complete type family Holes a b :: * canHaveHolesT :: a - b - Holes a b canHaveHolesT _ _ = undefined type instance Holes HasHoles Complete = HasHoles type instance Holes Complete HasHoles = HasHoles type instance Holes HasHoles HasHoles = HasHoles type instance Holes Complete Complete = HasHoles data Expression k a where EQuote :: a - String - Expression HasHoles a IntLit :: a - Int - Expression Complete a EArith :: a - ArithOp - Expression k1 a - Expression k2 a - Expression (Holes k1 k2) a deriving instance Typeable2 (Expression) deriving instance Data (Expression k a) data ArithOp = OpAdd | OpSub | OpMul | OpDiv deriving (Data, Typeable) Fails with: Couldn't match type `Complete' with `HasHoles' Expected type: a - String - Expression k a Actual type: a - String - Expression HasHoles a In the first argument of `z', namely `EQuote' In the first argument of `k', namely `z EQuote' When typechecking the code for `Data.Data.gunfold' in a standalone derived instance for `Data (Expression k a)': To see the code I am typechecking, use -ddump-deriv Not sure what you mean here — attoparsec does support unlimited lookahead, in the sense that a parser may fail arbitrarily late in the input stream, and backtrack to any previous state. Although attoparsec is a poor choice for programming language parsing, primarily because of the error messages. I guess I have an outdated notion of attoparsec. But yes, error messages seem to be the weak point of attoparsec. Also, the fact that it only accepts bytestrings makes it harder (but no impossible, since we can convert Strings to ByteStrings) to reuse the parser as a QuasiQuoter. So, I'll rephrase my question. What's the best choice for a library for parsing programming languages nowadays? ___ 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] ANNOUNCE: haskell-packages-0.1
I am happy to announce the first release of haskell-packages. http://haskell-suite.github.io/haskell-packages/ There are two cases when you may need haskell-packages: if you are writing a Haskell compiler (or any tool that processes Haskell source code, such as a static analyzer), or if you want to integrate with an existing Haskell compiler that uses haskell-packages. ## Writing a compiler If you are writing a compiler, you typically want to integrate it with Cabal, to be able to build ordinary Haskell packages. If you go the hard way, this involves: 1. **Parsing command line parameters**. Sounds easy — just take a list of files to compile. In reality you also need to handle package ids and package dbs, CPP options (`-DFOO=1`), language extension flags (`-XRankNTypes`) etc. To integrate with Cabal, you also need to tell it the list of installed packages, supported languages and extensions etc. 2. Actual **integration with Cabal** means understanding how Cabal works and hard-coding support for your compiler. And then getting it accepted and waiting for the next Cabal release. You may pretend that you are GHC or other compiler that is already supported by Cabal. It might work, but often it won't, for various reasons. Also, GHC's command line protocol is quite complex. 3. **Package management**. You need to implement a package db mechanism, which would let you to keep track of installed packages. Then you'd have to implement a `ghc-pkg`-like tool to manage those databases, for both Cabal and your users. **Or**, you can simply use this library! It already has command line options parsing, Cabal support, and package management. All you need to do is to provide the function to do actual compilation and tell a couple of other things about your compiler. See the `Distribution.HaskellSuite.Compiler` module for details. ## Using other compilers Some compilers produce artifacts that you may want to use. A good example is the `gen-iface` compiler from haskell-names which generates an *interface* for each module — the set of all named entities (functions, types, classes) that are exported by that module. This information can be then used either by other compilers, or by tools like IDEs. Assuming the compiler uses haskell-packages and exports its database type, it's very easy to use its artifacts. See `Distribution.HaskellSuite.Packages` for package resolution and `Distribution.HaskellSuite.Modules` for module resolution. ## Installation Note that haskell-packages uses (yet unreleased) haskell-src-exts 1.14. Get it [here][hse]. It doesn't matter what Cabal version you use together with haskell-packages, but if you want to invoke a haskell-packages compiler from Cabal (see [Usage](#usage)), you need to build our [fork of Cabal][Cabal]. Eventually it will be merged into Cabal. [hse]: https://github.com/haskell-suite/haskell-src-exts [Cabal]: https://github.com/feuerbach/Cabal ## Usage To compile a Haskell package using a haskell-packages tool: cabal install --haskell-suite -w $TOOL where `$TOOL` may be either a full path to the compiler, or just an executable name if it's in `$PATH`. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] question about type constructors
* TP paratribulati...@free.fr [2013-05-23 00:34:57+0200] Hi, In the program I am trying to write, I have a problem that can be reduced to the following dummy example: -- {-# LANGUAGE GADTs #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE IncoherentInstances #-} class PrettyPrint a where prettify :: a - String data Gender = Male | Female | Gender3 | Gender4 data Person :: Gender - * where Person :: String - Person b Child :: String - Person a - Person b - Person c instance PrettyPrint (Person a) instance PrettyPrint (Person Male) where prettify (Person name) = My name is ++ (show name) ++ and I am a male prettify (Child name person1 person2) = My name is ++ (show name) ++ and my parents are: ++ (prettify person1) ++ , ++ (prettify person2) main = do let p1 = Person Jim :: Person Male let p2 = Person Joe :: Person Male let p3 = Child Jack p1 p2 print $ prettify p1 print $ prettify p2 print $ prettify p3 -- The idea is that I want to implement PrettyPrint only for a subset of the possible types in Gender (through promotion process). Why? It would be longer to explain (it is a bit more complicated in my real program). Anyway, in the program above, I have found that with IncoherentInstances (and the empty instance definition for (Person a)), it is working, it is able to use the most specific instance corresponding to the current type (I don't know exactly why). For example, p1 and p2 are correctly printed above, because they are of type (Person Male) and because I have implemented PrettyPrint for (Person Male). But it does not work for p3, I obtain an error at runtime: - $ runghc test.hs My name is \Jim\ and I am a male My name is \Joe\ and I am a male test_typelost.hs: test_typelost.hs:16:10-31: No instance nor default method for class operation Main.prettify - The reason is that the information that p1 and p2 are Male seems to be lost when we construct the child Child Jack p1 p2, probably because GHC only sees that in the type signature of Child, we have a more general (Person a) - (Person b). So he tries to find an implementation of prettify in PrettyPrint (Person a), but there is none. Is there any workaround? The rule of thumb is that you should never use IncoherentInstances. The proper way to do it is: data Person :: Gender - * where Person :: String - Person b Child :: (PrettyPrint a, PrettyPrint b) = String - Person a - Person b - Person c Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] ANNOUNCE: new bridge! (prelude-prime)
I liked Andreas's idea (cited below). Hence the new package prelude-prime. https://github.com/feuerbach/prelude-prime http://hackage.haskell.org/package/prelude-prime Pull requests are welcome, but let's stick to widely agreed changes (like the Foldable/Traversable one). I think one of the reasons why other Preludes haven't been adopted is because they were too radical. Let's see whether people here can put their code where their mouth is :) Roman * Andreas Abel andreas.a...@ifi.lmu.de [2013-05-20 13:26:05+0200] Maybe instead of fiddling with the current Prelude (which might break backwards compatibility), we should design a new prelude which is not automatically loaded but contains roughly the current prelude (with the list functions generalized to collections) plus the modern type class stack: Functor, Applicative, Monad, Foldable, Traversable, Monoid etc. I am willing to write {-# LANGUAGE NoImplicitPrelude #-} import Base if I get a decent, modern standard set of functions that could be considered as the base vocabulary of modern Haskell programmers... I just do not want to think about the democratic process involved in this design... Cheers, Andreas ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] question about type constructors
* TP paratribulati...@free.fr [2013-05-23 13:23:36+0200] Roman Cheplyaka wrote: The rule of thumb is that you should never use IncoherentInstances. The proper way to do it is: data Person :: Gender - * where Person :: String - Person b Child :: (PrettyPrint a, PrettyPrint b) = String - Person a - Person b - Person c Thanks a lot. Now I am using FlexibleContexts, and it works correctly (see code below). I think I have understood the problem. However, I have still one question. In the code below, I have added data constructors Child2, Child3 (imagining a world where every people has three children). The problem is that I am compelled to repeat the context (PrettyPrint (Person a), PrettyPrint (Person b)) for each one of the constructors. Is there any way to specify the context only once? I have tried using forall, but without any success. No, because the type variables are independent across different constructors. They are (implicitly) existentially quantified, which becomes clearer if you rewrite your type as data Person (c :: Gender) = forall a b . (PrettyPrint (Person a), PrettyPrint (Person b)) = Child1 String (Person a) (Person b) | forall a b . (PrettyPrint (Person a), PrettyPrint (Person b)) = Child2 String (Person a) (Person b) | ... What you can do is factor out the Child type as data Child where Child :: ( PrettyPrint (Person a) , PrettyPrint (Person b) ) = String - Person a - Person b - Child data Person a where Child1 :: Child - Person c Child2 :: Child - Person c Child3 :: Child - Person c - {-# LANGUAGE GADTs #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleContexts #-} class PrettyPrint a where prettify :: a - String data Gender = Male | Female | Gender3 | Gender4 data Person :: Gender - * where Person :: String - Person b Child1 :: (PrettyPrint (Person a) , PrettyPrint (Person b) ) = String - Person a - Person b - Person c Child2 :: (PrettyPrint (Person a) , PrettyPrint (Person b) ) = String - Person a - Person b - Person c Child3 :: (PrettyPrint (Person a) , PrettyPrint (Person b) ) = String - Person a - Person b - Person c instance PrettyPrint (Person Male) where prettify (Person name) = My name is ++ (show name) ++ and I am a male prettify (Child1 name person1 person2) = My name is ++ (show name) ++ and my parents are: ++ (prettify person1) ++ , ++ (prettify person2) main = do let a = Person Jim :: Person Male let b = Person Joe :: Person Male let c = Child1 Jack a b :: Person Male print $ prettify a print $ prettify b print $ prettify c ___ 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
Re: [Haskell-cafe] ANNOUNCE: new bridge! (prelude-prime)
* Manuel Gómez tar...@gmail.com [2013-05-23 08:33:15-0430] On Thu, May 23, 2013 at 3:07 AM, Roman Cheplyaka r...@ro-che.info wrote: Pull requests are welcome, but let's stick to widely agreed changes (like the Foldable/Traversable one). I think one of the reasons why other Preludes haven't been adopted is because they were too radical. * Andreas Abel andreas.a...@ifi.lmu.de [2013-05-20 13:26:05+0200] Maybe instead of fiddling with the current Prelude (which might break backwards compatibility), we should design a new prelude which is not automatically loaded but contains roughly the current prelude (with the list functions generalized to collections) plus the modern type class stack: Functor, Applicative, Monad, Foldable, Traversable, Monoid etc. Is this strategy adequate for attacking the issue of the type class stack, though? Defining, say, a new Monad class with the desired Functor constraint wouldn’t be of much use, as everything else on Hackage (and on the GHC libraries!) would still use the “real” Monad. No, it definitely isn't. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] accessing a type variable in instance declaration
* TP paratribulati...@free.fr [2013-05-22 16:18:55+0200] Hi all, I wonder if there is some means to get a type variable value in the body of a class instance definition. It seems it is not possible (a workaround has already been given on this list), but I would like a confirmation. For example, imagine that I have a Tensor type constructor, that takes a type-level integer (representing the Tensor order) to make a concrete type: - instance Show (Tensor order) where show TensorVar str = show tensor ++ str ++ of order ++ (show (c2num order)) -- where c2num transforms a type-level integer to an integer, through typeclasses (see http://www.haskell.org/haskellwiki/The_Monad.Reader/Issue5/Number_Param_Types) I obtain a compilation error: order is not known in the body of the instance. Putting ScopedTypeVariable as extension does not change anything (http://www.haskell.org/ghc/docs/7.0-latest/html/users_guide/other-type-extensions.html#scoped-type-variables). You are confusing type and value variables. c2num order means apply the function 'c2num' to the value variable 'order', which is not defined. To get from a type to a value you can use a type class 'Sing' (for 'singleton') class Sing a where sing :: a instance Sing Zero where sing = Zero instance Sing a = Sing (Succ a) where sing = Succ sing After adding the appropriate constraint to the instance, you can write show $ c2num $ (sing :: order) Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] accessing a type variable in instance declaration
* TP paratribulati...@free.fr [2013-05-22 18:45:06+0200] Ok, thanks, I understand. Now, I'm stuck to compile this code (independent from my previous post, but related to it): --- {-# LANGUAGE DataKinds #-} {-# LANGUAGE KindSignatures #-} data Nat = Zero | Succ Nat type One = Succ Zero type Two = Succ One -- class Cardinal c where -- line 1 class Cardinal (c::Nat) where -- line 2 c2num :: c - Integer cpred :: (Succ c) - c cpred = undefined instance Cardinal Zero where c2num _ = 0 instance (Cardinal c) = Cardinal (Succ c) where c2num x = 1 + c2num (cpred x) main = do print $ show $ c2num (undefined::Succ (Succ Zero)) print $ show $ c2num (undefined::Two) - With line 2, I get: test_nat.hs:11:14: Kind mis-match Expected kind `OpenKind', but `c' has kind `Nat' In the type `c - Integer' In the class declaration for `Cardinal' With line 1 instead, I get: Kind mis-match The first argument of `Succ' should have kind `Nat', but `c' has kind `*' In the type `(Succ c) - c' In the class declaration for `Cardinal' So, in the first case, c has a too restricted kind, and in the second one, it has a too broad kind in the definition of cpred. I have tried several things without any success. How to compile that code? You seem to assume that Succ Zero will have type 'Succ 'Zero (i.e. the promoted type), but it's not the case — it still has type Nat, as always. On the other hand, the type 'Succ 'Zero has kind 'Nat and doesn't have any inhabitants — only types of kind * do. So, how to fix this depends on what you want. For example, you can change c2num to accept Proxy c instead of c. Or you can establish the connection between Succ Zero and 'Succ 'Zero — again, using a (slightly modified) Sing class. In the latter case, take a look at the 'singletons' package — it can do a lot of work for you. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to throw an error if using cabal-install version XYZ?
Perhaps I'm missing something, but why not just cabal-version: =1.18 ? It will constrain the Cabal version, not cabal-install, but judging from the fix[1] this is what you actually need. [1]: https://github.com/haskell/cabal/commit/d148336e97cda2e3585c453cf9af61bc3635131a Roman * Ryan Newton rrnew...@gmail.com [2013-05-22 22:50:08-0400] A cabal-install bug https://github.com/haskell/cabal/issues/1284 was fixed recently that pertains to building C libraries with profiling. As a result, I want a certain packagehttp://hackage.haskell.org/package/atomic-primops-0.1.0.2to test if cabal-install 0.17.0 is used, and throw a preemptive error. Otherwise this package fails in weird ways at runtime (it's a nasty one). I noticed with some surprise the following sequence: * $ cabal --version* * cabal-install version 1.16.0.2* * using version 1.16.0.3 of the Cabal library* * $ cabal clean* * $ cabal install* * $ cat dist/build/autogen/cabal_macros.h | grep VERSION_Cabal* * #define VERSION_Cabal 1.17.0* Alright, so that, in retrospect, makes sense. The version is which *my* library is linked with is the relevant one, not the one cabal-install was linked with [1]. So the natural next thought is to move the MIN_VERSION_Cabal test into Setup.hs, and force cabal to use it by setting the build type to Custom. But... I just learned from this ticket that the cabal macros are not available in Setup.hs: http://hackage.haskell.org/trac/hackage/ticket/326 Uh oh, what's left? -Ryan [1] P.S. Personally I'm now using a bash function like below, to force the two versions to be the same: function safe_cabal_install () { VER=`cabal --version | tail -n1 | awk '{ print $3 }'` cabal install --constraint=Cabal==$VER $* } ___ cabal-devel mailing list cabal-de...@haskell.org http://www.haskell.org/mailman/listinfo/cabal-devel ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] parsing a CSV file
* Roger Mason rma...@mun.ca [2013-05-21 12:22:53-0230] Thus far, I have: -- derived from RWH -- file: ch16/csv2.hs import Text.ParserCombinators.Parsec headerLines = endBy csvFile endHeader csvFile = endBy line eol line = sepBy cell (char ',') cell = many (noneOf ,\n) eol = char '\n' parseCSV :: String - Either ParseError [[String]] parseCSV input = parse csvFile (unknown) input parseHDR :: String - Either ParseError [[String]] parseHDR input = parse headerLines (unknown) input endHeader = string Energy Counts This loads into GHCi (7.6.2) OK. However, when I test it: parseHDR Bruker Nano GmbH Berlin, Germany\nEsprit 1.9\n\nDate: 02/05/2013 10:06:49 AM\nReal time: 15000\nEnergy Counts Not in scope: `parseHDR' which makes sense because ghci :t endHeader interactive:1:1: Not in scope: `endHeader' Clearly, my naiive implementation of endHeader is no good. Hi Roger, Not in scope means that that thing is not defined. So it's not a problem with your implementation, but with the way you load it. If you copy-paste your ghci session here, you may get further help. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] parsing a CSV file
* Roger Mason rma...@mun.ca [2013-05-21 13:33:47-0230] Hi Roman, On 05/21/2013 12:36 PM, Roman Cheplyaka wrote: Clearly, my naiive implementation of endHeader is no good. Hi Roger, Not in scope means that that thing is not defined. So it's not a problem with your implementation, but with the way you load it. If you copy-paste your ghci session here, you may get further help. Roman Starting with a clean ghci session I get this: ghci :l csv.hs [1 of 1] Compiling Main ( csv.hs, interpreted ) csv.hs:15:24: Couldn't match type `[Char]' with `Char' Expected type: Text.Parsec.Prim.Parsec String () [[String]] Actual type: Text.Parsec.Prim.ParsecT String () Data.Functor.Identity.Identity Char In the first argument of `parse', namely `headerLines' In the expression: parse headerLines (unknown) input In an equation for `parseHDR': parseHDR input = parse headerLines (unknown) input Failed, modules loaded: none. So this is the real error. If you read it carefully, it says that it expected [[String]] but got Char (i.e. [[[String]]]) as a result of the headerLines parser. I don't have time right now to look closer at your code, but I suggest studying the types of combinators you use (such as endBy) and trying to write down type signatures for the rest of the values you define. This way you'll find the error and better understand your program. A useful trick is to start ghci with -fdefer-type-errors and use :t to inspect types of various expressions that you encounter. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] DSL to English and back for game rule set?
You should definitely look at Grammatical Framework http://www.grammaticalframework.org/ * Matthew O'Connor thegreendra...@gmail.com [2013-05-19 14:27:33-0600] Hello all, I recognize this isn't directly a Haskell-related question, but as I'd like to solve this problem in Haskell figured it's applicable. Let me know if there's a better place to ask. I am interested in creating a DSL (or set of types) for describing rules for a computer game. I'd like the language to be able to be written out to readable and clear English. I'd also like to be able to recreate the representation by reading the English back in. The idea is that the DSL will be unambiguous in either English or its internal representation. My thinking is that this will avoid inconsistencies between the game rules and the text describing those rules to the players. I want the ruleset to be able to describe type of heroes and monsters, their abilities, the effects of their attacks, how they use resources, etc. I realize this may not be an efficient way to go about writing a game, but it seems like an interesting project. Some of my concerns are at what level the DSL should be written to allow for extensions for new heroes, monsters, etc. without having to just add very specific extensions every time a new hero or item is created. Does anyone have thoughts on how to proceed on this, previous work, and/or ways to investigate it? Thanks, Matthew ___ 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
Re: [Haskell-cafe] Compiler error in Parsec using ByteString
Hi, General advice here is to put type signatures for all non-trivial definitions. This way you can see exactly where compiler and you disagree on what the type of something should be. In this particular case, by following the above recipe, I see that one problem is that `emptyDef` has type `LanguageDef st` (where `LanguageDef` is a synonym for `GenLanguageDef String st Identity`) — i.e. it's not polymorphic in the stream type. (There might be other issues as well.) Roman * mukesh tiwari mukeshtiwari.ii...@gmail.com [2013-05-18 16:37:42+0530] Hello all, I am trying to write a small calculator using Parsec. Every thing went fine and I wrote this [1] and now I am trying to use ByteString to make it more faster but getting compiler error which I am not able to figure out. Could some one please tell me what is wrong with this code. In case of indentation error, code on hpaste[2] {-# LANGUAGE OverloadedStrings #-} import qualified Text.Parsec.Token as Token import Text.Parsec.Prim import Text.Parsec.Char import Text.Parsec.Expr import Text.Parsec.Combinator import Text.Parsec.Language import qualified Text.Parsec.ByteString.Lazy as T import qualified Data.ByteString.Lazy.Char8 as BS import Control.Applicative hiding ( ( | ) , many ) import Data.Maybe ( fromJust ) languageDef = emptyDef { Token.commentStart = /* , Token.commentEnd = */ , Token.commentLine= // , Token.nestedComments = False , Token.identStart = letter | char '_' , Token.identLetter= alphaNum | oneOf _' , Token.opStart= Token.opLetter emptyDef , Token.opLetter = oneOf :!#$%*+./=?@\\^|-~ , Token.reservedOpNames= [* , / , ^ , + , - ] , Token.reservedNames = [] , Token.caseSensitive = True } lexer = Token.makeTokenParser languageDef identifier = Token.identifier lexer reserved = Token.reserved lexer operator = Token.operator lexer reservedOp = Token.reservedOp lexer natural = Token.natural lexer integer = Token.integer lexer float = Token.float lexer lexeme = Token.lexeme lexer parens = Token.parens lexer whiteSpace = Token.whiteSpace lexer semi = Token.semi lexer comma = Token.comma lexer colon = Token.colon lexer dot = Token.dot lexer semiSep = Token.semiSep lexer commaSep = Token.commaSep lexer data Expr = Num Integer | Add Expr Expr | Sub Expr Expr | Mul Expr Expr | Div Expr Expr | Exp Expr Expr deriving Show exprCal:: T.Parser Expr exprCal= buildExpressionParser table factor table = [ [ op ^ Exp AssocRight ] , [ op * Mul AssocLeft, op / Div AssocLeft ] , [ op + Add AssocLeft, op - Sub AssocLeft ] ] where op s f assoc = Infix ( reservedOp s return f ) assoc factor :: T.Parser Expr factor = parens exprCal | Num $ integer calExpression :: Expr - Integer calExpression ( Num n ) = n calExpression ( Add e1 e2 ) = calExpression e1 + calExpression e2 calExpression ( Sub e1 e2 ) = calExpression e1 - calExpression e2 calExpression ( Mul e1 e2 ) = calExpression e1 * calExpression e2 calExpression ( Div e1 e2 ) = div ( calExpression e1 ) ( calExpression e2 ) calExpression ( Exp e1 e2 ) = calExpression e1 ^ ( calExpression e2 ) calculator :: String - Integer calculator expr = case parse ( whiteSpace exprCal ) ( BS.pack expr ) of Left msg - error failed to parse Right ( val ) - calExpression val *Main :load /Users/mukeshtiwari/Programming/Code/Compilers/ParsecExample.hs [1 of 1] Compiling Main ( /Users/mukeshtiwari/Programming/Code/Compilers/ParsecExample.hs, interpreted ) /Users/mukeshtiwari/Programming/Code/Compilers/ParsecExample.hs:56:36: Couldn't match type `[Char]' with `BS.ByteString' Expected type: OperatorTable BS.ByteString () Data.Functor.Identity.Identity Expr Actual type: [[Operator String () Data.Functor.Identity.Identity Expr]] In the first argument of `buildExpressionParser', namely `table' In the expression: buildExpressionParser table factor In an equation for `exprCal': exprCal = buildExpressionParser table factor /Users/mukeshtiwari/Programming/Code/Compilers/ParsecExample.hs:67:11: Couldn't match type `[Char]' with `BS.ByteString' Expected type: ParsecT BS.ByteString () Data.Functor.Identity.Identity Expr Actual type: ParsecT String () Data.Functor.Identity.Identity Expr In the return type of a call of `parens' In the first argument of `(|)', namely `parens exprCal' In the expression: parens exprCal | Num $ integer
[Haskell-cafe] Non-deterministic behaviour of aeson's parser
I am observing a non-deterministic behaviour of aeson's parser. I'm writing here in addition to filing a bug report [1] to draw attention to this (pretty scary) problem. To try to reproduce this problem, do this: git clone https://gist.github.com/5604887.git aeson cd aeson ghc aeson.hs ./aeson | sort | uniq -c This is my result: 32 Left key \module\ not present 55 Left When parsing the record SymValue of type Main.SymValueInfo the key fixity was not present. 1913 Right () Can others reproduce this in their environments? Does anyone have ideas about where the bug may lie? Many aeson's dependencies do unsafe IO stuff that could lead to such consequences. Roman [1]: https://github.com/bos/aeson/issues/125 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Non-deterministic behaviour of aeson's parser
Indeed it looks like a bug in hashable — it goes away with hashable-1.1.2.5. Building with -f-sse2 results in a linker error Loading package hashable-1.2.0.7 ... linking ... ghc: /home/feuerbach/tmp/aeson/.cabal-sandbox/lib/i386-linux-ghc-7.6.3/hashable-1.2.0.7/libHShashable-1.2.0.7.a: unknown symbol `hashable_siphash24_sse2' ghc: unable to load package `hashable-1.2.0.7' Roman * Gregory Collins g...@gregorycollins.net [2013-05-18 22:19:38+0200] First off, everyone reporting results to this thread: your bug report would be much more helpful if you included your OS/architecture/GHC version combo, as well as the results of re-running the tests if you build hashable with cabal install -f-sse2. I have a funny feeling that this is a bug in hashable or unordered-containers. I'm guessing hashable, especially because of this: https://github.com/tibbe/hashable/issues/66 and because hashable has had subtle bugs in its C code before (see https://github.com/tibbe/hashable/issues/60). G On Sat, May 18, 2013 at 6:25 PM, Roman Cheplyaka r...@ro-che.info wrote: I am observing a non-deterministic behaviour of aeson's parser. I'm writing here in addition to filing a bug report [1] to draw attention to this (pretty scary) problem. To try to reproduce this problem, do this: git clone https://gist.github.com/5604887.git aeson cd aeson ghc aeson.hs ./aeson | sort | uniq -c This is my result: 32 Left key \module\ not present 55 Left When parsing the record SymValue of type Main.SymValueInfo the key fixity was not present. 1913 Right () Can others reproduce this in their environments? Does anyone have ideas about where the bug may lie? Many aeson's dependencies do unsafe IO stuff that could lead to such consequences. Roman [1]: https://github.com/bos/aeson/issues/125 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -- Gregory Collins g...@gregorycollins.net ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] A use case for *real* existential types
* o...@okmij.org o...@okmij.org [2013-05-11 05:26:55-] I must say though that I'd rather prefer Adres solution because his init init :: (forall a. Inotify a - IO b) - IO b ensures that Inotify does not leak, and so can be disposed of at the end. So his init enforces the region discipline and could, after a trivial modification to the code, automatically do a clean-up of notify descriptors -- something you'd probably want to do. Well, it is still possible to escape if one wants, using an existential type: data Escape = forall a . Escape (Inotify a) (Watch a) main = do Escape inotify watch - init $ \inotify - do watch - addWatch inotify foo return $ Escape inotify watch rmWatch inotify watch This is because here, unlike in the ST case, the monad itself (IO) is not tagged. It's probably not easy to do this by accident, but I think ensures is too strong a word here. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Mutually recursive modules
I wonder whether it's always possible to break cycles using GHC's .hs-boot files. Consider the following schematic example: module A where import B data A f :: B - A f = undefined B.g module B where import A data B g :: A - B g = undefined A.f A.hs-boot must give a type signature for f, and since the signature contains 'B', it must import 'B'. Ditto for B.hs-boot — it must import 'A'. Even if we treat all imports as {-# SOURCE #-}, there is still a cycle between the hs-boot files. So, am I right in understanding that these recursive modules cannot be compiled by GHC at all? Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Mutually recursive modules
Ah yes, thank you! * Francesco Mazzoli f...@mazzo.li [2013-05-08 08:51:12+0100] At Wed, 8 May 2013 09:46:08 +0300, Roman Cheplyaka wrote: I wonder whether it's always possible to break cycles using GHC's .hs-boot files. Consider the following schematic example: module A where import B data A f :: B - A f = undefined B.g module B where import A data B g :: A - B g = undefined A.f A.hs-boot must give a type signature for f, and since the signature contains 'B', it must import 'B'. Ditto for B.hs-boot — it must import 'A'. Even if we treat all imports as {-# SOURCE #-}, there is still a cycle between the hs-boot files. So, am I right in understanding that these recursive modules cannot be compiled by GHC at all? This configuration works for me: A.hs: module A where import B data A f :: B - A f = undefined B.g A.hs-boot: module A where import {-# SOURCE #-} B data A f :: B - A B.hs: module B where import {-# SOURCE #-} A data B g :: A - B g = undefined A.f B.hs-boot: module B where data B Then I can compile them: bitonic@clay /tmp % ghc -c B.hs-boot bitonic@clay /tmp % ghc -c A.hs-boot bitonic@clay /tmp % ghc -c B.hs bitonic@clay /tmp % ghc -c A.hs Francesco ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Lambda Calculus question on equivalence
IIRC, Barendregt'84 monography (The Lambda Calculus: Its Syntax and Semantics) has a significant part of it devoted to this question. * Ian Price ianpric...@googlemail.com [2013-05-02 20:47:07+0100] Hi, I know this isn't perhaps the best forum for this, but maybe you can give me some pointers. Earlier today I was thinking about De Bruijn Indices, and they have the property that two lambda terms that are alpha-equivalent, are expressed in the same way, and I got to wondering if it was possible to find a useful notion of function equality, such that it would be equivalent to structural equality (aside from just defining it this way), though obviously we cannot do this in general. So the question I came up with was: Can two normalised (i.e. no subterm can be beta or eta reduced) lambda terms be observationally equivalent, but not alpha equivalent? By observationally equivalent, I mean A and B are observationally equivalent if for all lambda terms L: (L A) is equivalent to (L B) and (A L) is equivalent to (B L). The definition is admittedly circular, but I hope it conveys enough to understand what I'm after. My intuition is no, but I am not sure how to prove it, and it seems to me this sort of question has likely been answered before. Cheers -- Ian Price -- shift-reset.com Programming is like pinball. The reward for doing it well is the opportunity to do it again - from The Wizardy Compiled ___ 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
Re: [Haskell-cafe] GSoC proposal: Haskell AST-based refactoring and API upgrading tool
* Niklas Hambüchen m...@nh2.me [2013-04-29 14:00:23+0800] I would like to propose the development of source code refactoring tool that operates on Haskell source code ASTs and lets you formulate rewrite rules written in Haskell. Hi Niklas, This is a great idea. I talked about it at HIW last year[1] and have been working on it since then. [1]: http://www.youtube.com/watch?v=Ae-6uIMQPmU 1. What you call a full-source AST is already present in haskell-src-exts (under Annotated subtree). It /almost/ satisfies pretty . parse = id, (one thing it fails to do is to preserve tabs), and fixing it should be definitely easier than starting from scratch. 2. HSE has two pretty-printers: an exact one, and one that ignores annotations and pretty-prints in its own style. It's important to have a mixture of both, so that we can pretty-print generated snippets and splice them into an already formatted AST. A friend of mine, Pavel Poukh, is working on a pretty-printer that produces an annotated tree instead of a flat string, and AFAIK that work is close to done. [2]: https://github.com/Pnom/haskell-ast-pretty 3. A major thing that I devoted my time to is name resolution and package management [3,4], which are necessary for the tool to work. [3]: https://github.com/feuerbach/haskell-names [4]: https://github.com/feuerbach/haskell-packages They are also close to done. 4. As for the tool itself, I have a crude prototype [5], but I haven't updated it for a while. [5]: https://github.com/feuerbach/hasfix 5. The user interface is, of course, an important topic by itself. I was thinking of something less expressive and more declarative, but your idea is also interesting. Let's discuss this separately. Regarding this topic as a GSoC project, I'm not so sure this is a good idea. As a past GSoC student myself, I feel that new projects (as opposed to established projects with existing user base and development team) have much greater risks. (This is also backed up by data [6].) But if you (or anyone else who happens to read this) would like to get involved, please get in touch with me! [6]: http://www.gwern.net/Haskell Summer of Code Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] pattern matching on data families constructors
Let's look at it from the operational perspective. In the GADT case, the set of possibilities is fixed in advance (closed). Every GADT constructor has a corresponding tag (a small integer) which, when pattern-matching, tells us which branch to take. In the data family case, the set of possibilities is open. It is harder to do robust tagging over all the instances, given that new instances can be added after the module is compiled. The right way to do what you want is to use a type class and associate your data family with that class: class C a where data D a a :: D a - a instance C Int where data D Int = DInt Int a (DInt x) = x instance C Bool where data D Bool = DBool Bool a (DBool x) = x Roman * Alexey Egorov elect...@list.ru [2013-04-25 20:29:16+0400] Hi, suppose that there is following data family: data family D a data instance D Int = DInt Int data instance D Bool = DBool Bool it is not possible to match on constructors from different instances: -- type error a :: D a - a a (DInt x) = x a (DBool x) = x however, following works: data G :: * - * where GInt :: G Int GBool :: G Bool b :: G a - D a - a b GInt (DInt x) = x b GBool (DBool x) = x The reason why second example works is equality constraints (a ~ Int) and (a ~ Bool) introduced by GADT's constructors, I suppose. I'm curious - why data families constructors (such as DInt and DBool) doesn't imply such constraints while typechecking pattern matching? Thanks. ___ 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
Re: [Haskell-cafe] createProcess interferes with sockets?
* Evan Laforge qdun...@gmail.com [2013-04-22 12:41:33+0530] On Sun, Apr 21, 2013 at 9:25 PM, Donn Cave d...@avvanta.com wrote: Quoth Evan Laforge qdun...@gmail.com, sleep = Process.createProcess (Process.proc sleep [5]) sleep = Process.createProcess ((Process.proc sleep [5]) {Process.close_fds = True}) - Because the client uses buffered I/O (hGetContents in this case, but hGet-anything would be the same), it doesn't see the server response until a) buffer full, or b) end of file (server closes connection.) - The server does close the connection, but after the sleep process has forked off with a copy of the connection fd. If it doesn't close that fd explicitly, it holds it open until process exit (5 seconds.) Oh I see, because the subprocess inherits the socket connection. That makes sense, though it's tricky. Tricky tricky unix. Why does fork() have to be so complicated? You probably want to set FD_CLOEXEC flag on your sockets. This will cause execve to close them in the child process. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] version of containers fixed by template-haskell?
* Johannes Waldmann waldm...@imn.htwk-leipzig.de [2013-04-17 08:10:21+] (Isn't it somewhat bold of cabal-install to offer to break ghc-7.6.2? like, this will completely hose the compiler?) ghc is the package that provides the GHC API. Breaking it should not affect the compiler itself, since it is statically linked. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] version of containers fixed by template-haskell?
On second thought, are you trying to install it globally? ghc is installed globally, and local packages should not break it. * Johannes Waldmann waldm...@imn.htwk-leipzig.de [2013-04-17 08:36:23+] Roman Cheplyaka roma at ro-che.info writes: ghc is the package that provides the GHC API. Breaking it should not affect the compiler itself, since it is statically linked. Yes. But once ghc (the package) is broken, it cannot be fixed (except by re-installing ghc (the compiler))? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Contravariant applicatives, monads and arrows (was ANN: rematch, an library for composable assertions with human readable failure messages)
* Stephen Tetley stephen.tet...@gmail.com [2013-04-16 19:48:47+0100] On 16 April 2013 16:12, Alejandro Serrano Mena trup...@gmail.com wrote: Hi, First of all, let me say that this work on matchers is really useful :) Following Roman advice, I'm trying to find a more principled approach that could be useful for this library. It seems that Match could easily be converted to Either and thus made into Functor, Applicative, Alternative and Monad. That would allow to write things like: Have you seen Ralf Hinze, Johan Jeuring and Andreas Loeh's paper on Contracts? The found their Contract datatype formed a comonad - at the time this seemed to be one of the few (non-synthetic) uses of comonads. Their Contract datatype is contravariant, just like Tom's Matcher. So it cannot be a comonad. It's their contracted function type which is a (very simple) comonad — but I'm not sure how it can be useful here. (I only skipped very quickly through the paper, so I may be missing something.) Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Contravariant applicatives, monads and arrows (was ANN: rematch, an library for composable assertions with human readable failure messages)
You are right Alejandro, arrows are a perfect fit here. (Most of it is possible with monads as well, but arrows are useful to maintain static names of the properties.) Here's what I've come up with: https://gist.github.com/feuerbach/5409326 Now everyItem and hasJust have types everyItem :: Matcher [a] a hasJust :: Matcher (Maybe a) a (similarly for all other functions) This allows us to write myProp = everyItem hasJust is 3 or even myProp = proc list - do mbItem - everyItem - list item - hasJust - mbItem is 3 - item Roman * Alejandro Serrano Mena trup...@gmail.com [2013-04-16 17:12:51+0200] Hi, First of all, let me say that this work on matchers is really useful :) Following Roman advice, I'm trying to find a more principled approach that could be useful for this library. It seems that Match could easily be converted to Either and thus made into Functor, Applicative, Alternative and Monad. That would allow to write things like: User $ runMatch (isNot isEmpty) name * runMatch (hasItem (is '@')) email However, I'm also thinking about the correct way to combine matchers to get bigger matchers. Basically, if I have matchers on every field of a record, can I get a matcher for the entire one? My first idea was to make Matcher a functor. However, what I come was a contravariant functor: given (a - b) and Matcher b, I can easily construct a Matcher a by running the one in b over this function. So we have: contramap :: (a - b) - Matcher b - Matcher a My first question is: is there any structure similar to applicative functors or monads which work on these kind of contravariant functors? This also brought into my mind to see Matcher a just as functions a - Match and derive its properties from there. This may give better results that the above mentioned idea of looking it as a - Either String a, because in this latter case we have a in covariant and contravariant positions and it's difficult to get anything. On the other hand, it seems very easy, from a Matcher a and a Matcher b, to get a Matcher (a,b). This reminds me a bit about arrows, but without output parameters. Does it make sense? I've always been reluctant to arrows because I don't fully understand them, but maybe this is a good moment to learn. Do any of this make sense? I would really like to contribute to this great library! :) 2013/4/16 Tom Crayford tcrayf...@gmail.com: Roman, Thanks for the feedback! I'd originally left the QuickCheck and HUnit implementations in this library for convenience, thinking that there aren't going to be many people who care about the transitive dep. But you care, so I'm happy moving them out of core. I'll release a 0.2 with both the HUnit and the QuickCheck runners in separate libraries soonish. Thanks for the haddock tip and the implementation tips. Re the Control namespace, these matchers aren't exclusively a testing tool. I've been using the core api for other purposes as well (primarily for validating forms in user interfaces in conjunction with digestive-functors). I couldn't figure anything better to put it in apart from Control (I definitely don't want it in Test, even though that's going to be what most people use it for). I guess it could be in `Data`, but that doesn't sound much better to me. I'm not amazingly strong at building more principled interfaces right now, so I guess that's something I'll improve on. Are there any concrete suggestions you have there? I'd *like* these to have an `Alternative` instance, but making `Applicative`/`Functor` instances is beyond me right now (I guess I'd have to change the core API for that to work out). Tom ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Monad fold
* Christopher Howard christopher.how...@frigidcode.com [2013-04-16 04:35:39-0800] So, I'm doing something like this foldl (=) someA list :: Monad m = m a where list :: Monad m = [a - m a], someA :: Monad m = m a Is there a more concise way to write this? I don't think foldM is what I want -- or is it? I don't think it can get any more concise. (No, foldM isn't what you want.) But you most probably should prefer the right fold in this case. (Unless you don't care about efficiency.) Something like someA = foldr (=) return list should do. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Monad fold
Right. See also this discussion: http://www.haskell.org/pipermail/libraries/2009-July/012106.html Roman * Tom Ellis tom-lists-haskell-cafe-2...@jaguarpaw.co.uk [2013-04-16 14:49:48+0100] On Tue, Apr 16, 2013 at 01:53:19PM +0100, Oliver Charles wrote: On 04/16/2013 01:47 PM, Lyndon Maydwell wrote: You could do: runKleisli . mconcat . map Kleisli :: Monoid (Kleisli m a b) = [a - m b] - a - m b Would that work for you? I can't find an instance for Monoid (Kleisli m a b) in `base`, so presumably the author would also have to write this instance? If so - would that really be any different to using that fold? It doesn't make sense anyway. It would have to be Kleisli m a a which would presumably require a newtype. Tom ___ 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
Re: [Haskell-cafe] ANN: rematch, an library for composable assertions with human readable failure messages
Hi Tom, This is a neat idea! I'd like to use something like this in smallcheck and test-framework-golden. The main obstacle to that is that your package depends on QuickCheck and HUnit, and every package using rematch would transitively depend on them, too. This has little sense, especially for smallcheck which is in some sense a replacement for QuickCheck. The alternative is either to put HUnit and QuickCheck interfaces in the separate packages, or try to get them accepted into the HUnit and QuickCheck directly. Below are some more suggestions regarding the package: 1. You need to escape single and double quotes in the haddock documentation; otherwise they'll be turned into (bad) links. 2. Your 'join' function is a special case of 'intercalate' from Data.List. 3. The Control namespace doesn't quite match the purpose of your modules, since they are not about control flow. Perhaps Test? I also wonder whether there is a more principled approach to such an API — say, based on applicative functors. Roman * Tom Crayford tcrayf...@gmail.com [2013-04-16 10:17:48+0100] I kept on running into this thing where I was calling error in quickcheck to get good error messages about the things I was comparing. In Java land, this stuff is handled by Hamcrest: a library for composable assertions with good error messages. This library is basically a port of hamcrest's core api, but I've been very pleased with how it turned out. I've been using this in tests for production code for a month or so now, and I'm very pleased with it. Running a matcher (in this example in an hunit test) looks like this: expect [1] (is [1]) The core API is very simple: data Matcher a = Matcher { match :: a - Bool -- ^ A function that returns True if the matcher should pass, False if it should fail , description :: String -- ^ A description of the matcher (usually of its success conditions) , describeMismatch :: a - String -- ^ A description to be shown if the match fails. } This means you can add/write your own matchers happily, which occasionally means you can write *very* nice test code (here's an example of using a custom matcher for checking the state of an issue in a hypothetical issue tracking app): expect latestIssue (hasState Resolved) -- I removed the supporting code to make this assertion actually run, -- this email is already pretty long. There are numerous matchers (and functions for creating matchers) in the rematch library, including some composition functions that provide good failure messages. There are some shims to hook rematch into the common haskell test frameworks (specifically hunit and quickcheck). The two libraries are up on hackage: http://hackage.haskell.org/package/rematch http://hackage.haskell.org/package/rematch-text The code is all up on github: http://github.com/tcrayford/rematch I get rather frustrated when my tests give bad failure explanations, and using rematch goes a long way to fix that. Lastly, rematch is pretty isolated from test frameworks/etc, with a very small and easy to understand surface api. Hopefully it'll help with the thing I've seen in other languages (cough ruby cough) with every test framework reinventing this idea, and not all frameworks having all the matchers I want to use. Let me know if you have any feedback/thoughts Tom ___ 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
Re: [Haskell-cafe] ANN: rematch, an library for composable assertions with human readable failure messages
* Tom Crayford tcrayf...@gmail.com [2013-04-16 15:24:07+0100] Re the Control namespace, these matchers aren't exclusively a testing tool. I've been using the core api for other purposes as well (primarily for validating forms in user interfaces in conjunction with digestive-functors). I couldn't figure anything better to put it in apart from Control (I definitely don't want it in Test, even though that's going to be what most people use it for). I guess it could be in `Data`, but that doesn't sound much better to me. Yeah, the distinction between Control and Data is often borderline. Also, I've just recalled that Control.Unification also uses the Control namespace, although I don't see any rationale behind that. It's not that important anyway. I'm not amazingly strong at building more principled interfaces right now, so I guess that's something I'll improve on. Are there any concrete suggestions you have there? I'd *like* these to have an `Alternative` instance, but making `Applicative`/`Functor` instances is beyond me right now (I guess I'd have to change the core API for that to work out). I'll see if I can sketch something in the next couple of days. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Contravariant applicatives, monads and arrows (was ANN: rematch, an library for composable assertions with human readable failure messages)
My idea was to convert Matcher to be a covariant functor. It would be essentially a Matcher which has been applied to the tested value. And the type argument would denote the result of a computation. For example, consider hasRight :: (Show a, Show b) = Matcher b - Matcher (Either a b) Instead it could have type hasRight :: F (Either a b) - F b ... and you then could test 'b' further. F, of course, would handle errors. But also it could record the chain of functions, so that it could print it in case of failure, like it Tom's code. (I guess that means that F has to be a monad. Also it (intentionally) wouldn't satisfy any usual laws, because we need to record all the computational steps.) Or, indeed, you could both preserve the input and add an output, which would make it a profunctor (and probably a category/arrow). Roman * Alejandro Serrano Mena trup...@gmail.com [2013-04-16 17:12:51+0200] Hi, First of all, let me say that this work on matchers is really useful :) Following Roman advice, I'm trying to find a more principled approach that could be useful for this library. It seems that Match could easily be converted to Either and thus made into Functor, Applicative, Alternative and Monad. That would allow to write things like: User $ runMatch (isNot isEmpty) name * runMatch (hasItem (is '@')) email However, I'm also thinking about the correct way to combine matchers to get bigger matchers. Basically, if I have matchers on every field of a record, can I get a matcher for the entire one? My first idea was to make Matcher a functor. However, what I come was a contravariant functor: given (a - b) and Matcher b, I can easily construct a Matcher a by running the one in b over this function. So we have: contramap :: (a - b) - Matcher b - Matcher a My first question is: is there any structure similar to applicative functors or monads which work on these kind of contravariant functors? This also brought into my mind to see Matcher a just as functions a - Match and derive its properties from there. This may give better results that the above mentioned idea of looking it as a - Either String a, because in this latter case we have a in covariant and contravariant positions and it's difficult to get anything. On the other hand, it seems very easy, from a Matcher a and a Matcher b, to get a Matcher (a,b). This reminds me a bit about arrows, but without output parameters. Does it make sense? I've always been reluctant to arrows because I don't fully understand them, but maybe this is a good moment to learn. Do any of this make sense? I would really like to contribute to this great library! :) 2013/4/16 Tom Crayford tcrayf...@gmail.com: Roman, Thanks for the feedback! I'd originally left the QuickCheck and HUnit implementations in this library for convenience, thinking that there aren't going to be many people who care about the transitive dep. But you care, so I'm happy moving them out of core. I'll release a 0.2 with both the HUnit and the QuickCheck runners in separate libraries soonish. Thanks for the haddock tip and the implementation tips. Re the Control namespace, these matchers aren't exclusively a testing tool. I've been using the core api for other purposes as well (primarily for validating forms in user interfaces in conjunction with digestive-functors). I couldn't figure anything better to put it in apart from Control (I definitely don't want it in Test, even though that's going to be what most people use it for). I guess it could be in `Data`, but that doesn't sound much better to me. I'm not amazingly strong at building more principled interfaces right now, so I guess that's something I'll improve on. Are there any concrete suggestions you have there? I'd *like* these to have an `Alternative` instance, but making `Applicative`/`Functor` instances is beyond me right now (I guess I'd have to change the core API for that to work out). Tom ... ___ 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