From P.Achten at cs.ru.nl Mon May 1 13:55:08 2017 From: P.Achten at cs.ru.nl (Peter Achten) Date: Mon, 1 May 2017 15:55:08 +0200 Subject: [Haskell-cafe] Final call for papers: Trends in Functional Programming, 19-21 june 2017, University of Kent, Canterbury Message-ID: <9fab29d1-9d5c-14fb-9e9d-6aa673615498@cs.ru.nl> ----------------------------- F I N A L C A L L F O R P A P E R S ----------------------------- ======== TFP 2017 =========== 18th Symposium on Trends in Functional Programming 19-21 June, 2017 University of Kent, Canterbury https://www.cs.kent.ac.uk/events/tfp17/index.html The symposium on Trends in Functional Programming (TFP) is an international forum for researchers with interests in all aspects of functional programming, taking a broad view of current and future trends in the area. It aspires to be a lively environment for presenting the latest research results, and other contributions (see below). Authors of draft papers will be invited to submit revised papers based on the feedback receive at the symposium. A post-symposium refereeing process will then select a subset of these articles for formal publication. TFP 2017 will be the main event of a pair of functional programming events. TFP 2017 will be accompanied by the International Workshop on Trends in Functional Programming in Education (TFPIE), which will take place on 22 June. The TFP symposium is the heir of the successful series of Scottish Functional Programming Workshops. Previous TFP symposia were held in * Edinburgh (Scotland) in 2003; * Munich (Germany) in 2004; * Tallinn (Estonia) in 2005; * Nottingham (UK) in 2006; * New York (USA) in 2007; * Nijmegen (The Netherlands) in 2008; * Komarno (Slovakia) in 2009; * Oklahoma (USA) in 2010; * Madrid (Spain) in 2011; * St. Andrews (UK) in 2012; * Provo (Utah, USA) in 2013; * Soesterberg (The Netherlands) in 2014; * Inria Sophia-Antipolis (France) in 2015; * and Maryland (USA) in 2016. For further general information about TFP please see the TFP homepage. (http://www.tifp.org/). == SCOPE == The symposium recognizes that new trends may arise through various routes. As part of the Symposium's focus on trends we therefore identify the following five article categories. High-quality articles are solicited in any of these categories: Research Articles: leading-edge, previously unpublished research work Position Articles: on what new trends should or should not be Project Articles: descriptions of recently started new projects Evaluation Articles: what lessons can be drawn from a finished project Overview Articles: summarizing work with respect to a trendy subject Articles must be original and not simultaneously submitted for publication to any other forum. They may consider any aspect of functional programming: theoretical, implementation-oriented, or experience-oriented. Applications of functional programming techniques to other languages are also within the scope of the symposium. Topics suitable for the symposium include, but are not limited to: Functional programming and multicore/manycore computing Functional programming in the cloud High performance functional computing Extra-functional (behavioural) properties of functional programs Dependently typed functional programming Validation and verification of functional programs Debugging and profiling for functional languages Functional programming in different application areas: security, mobility, telecommunications applications, embedded systems, global computing, grids, etc. Interoperability with imperative programming languages Novel memory management techniques Program analysis and transformation techniques Empirical performance studies Abstract/virtual machines and compilers for functional languages (Embedded) domain specific languages New implementation strategies Any new emerging trend in the functional programming area If you are in doubt on whether your article is within the scope of TFP, please contact the TFP 2017 program chairs, Scott Owens and Meng Wang. == BEST PAPER AWARDS == To reward excellent contributions, TFP awards a prize for the best paper accepted for the formal proceedings. TFP traditionally pays special attention to research students, acknowledging that students are almost by definition part of new subject trends. A student paper is one for which the authors state that the paper is mainly the work of students, the students are listed as first authors, and a student would present the paper. A prize for the best student paper is awarded each year. In both cases, it is the PC of TFP that awards the prize. In case the best paper happens to be a student paper, that paper will then receive both prizes. == PAPER SUBMISSIONS == Acceptance of articles for presentation at the symposium is based on a lightweight peer review process of extended abstracts (4 to 10 pages in length) or full papers (20 pages). The submission must clearly indicate which category it belongs to: research, position, project, evaluation, or overview paper. It should also indicate which authors are research students, and whether the main author(s) are students. A draft paper for which ALL authors are students will receive additional feedback by one of the PC members shortly after the symposium has taken place. We use EasyChair for the refereeing process. Papers must be submitted at: https://easychair.org/conferences/?conf=tfp17 Papers must be written in English, and written using the LNCS style. For more information about formatting please consult the Springer LNCS web site: http://www.springer.com/computer/lncs?SGWID=0-164-6-793341-0 == INVITED SPEAKERS == Conor McBride University of Strathclyde (UK) Cătălin Hriţcu INRIA Paris (FR) == IMPORTANT DATES == Submission of draft papers: 5 May, 2017 Notification: 12 May, 2017 Registration: 11 June, 2017 TFP Symposium: 19-21 June, 2017 Student papers feedback: 29 June, 2017 Submission for formal review: 2 August, 2017 Notification of acceptance: 3 November, 2017 Camera ready paper: 2 December, 2017 == PROGRAM COMMITTEE == Co-Chairs Meng Wang University of Kent (UK) Scott Owens University of Kent (UK) PC Jeremy Yallop University of Cambridge (UK) Nicolas Wu University of Bristol (UK) Laura Castro University of A Coruña (ES) Gabriel Scherer Northeastern University (US) Edwin Brady University of St Andrews (UK) Janis Voigtländer Radboud University Nijmegen (NL) Peter Achten Radboud University Nijmegen (NL) Tom Schrijvers KU Leuven (BE) Matthew Fluet Rochester Institute of Technology (US) Mauro Jaskelioff CIFASIS/Universidad Nacional de Rosario (AG) Patricia Johann Appalachian State University (US) Bruno Oliveira The University of Hong Kong (HK) Rita Loogen Philipps-Universität Marburg (GE) David Van Horn University of Marylan (US) Soichiro Hidaka Hosei University (JP) Michał Pałka Chalmers University of Technology (SE) Sandrine Blazy University of Rennes 1 - IRISA (FR) From sergueyz at gmail.com Tue May 2 11:52:41 2017 From: sergueyz at gmail.com (Serguey Zefirov) Date: Tue, 2 May 2017 14:52:41 +0300 Subject: [Haskell-cafe] Cabal and IPv6 In-Reply-To: References: Message-ID: 2017-04-29 8:58 GMT+03:00 : > ping doesn't seem to have an ip-version-agnostic setting. > cabal could try both ping and ping6. > Question is: Why does cabal even require ping? pinging a host is useful in > network monitoring, but I have yet to see a situation where it is even > helpful to establish a connection. > Most probably I was not quite clear in the description of the situation. Cabal does not require ping6. It was me trying to resolve the problem who tried ping and ping6, not cabal. And I found that all hosts on the machine are accessible only through IPv6. Cabal internally uses IPv4 calls/data structures, it seems. And fails. A proposition: is it even remotely good idea to replace in cabal source code all calls to web API to invocation of curl/wget? > > > Good question! At the moment we don’t have ipv6 enabled on our cdn — > > it looks like it was only recently made available to configure that way > > for general use [1]. I’ve talked to other admins, and I hope we can > just > > turn on the switch and have it work going forward. Until then, here’s > > the ipv6 address of the current origin hackage server, which can perhaps > > be used in the meantime? > > > > 2001:4800:7821:103:be76:4eff:fe04:b11a > > > > [1] https://www.fastly.com/blog/ipv6-fastly > > > > Cheers, > > Gershom > > > > On April 26, 2017 at 5:43:37 PM, Serguey Zefirov (sergueyz at gmail.com) > > wrote: > >> I have found that Cabal does not work on IPv6-only networks (which my > >> machine happen to be part of). > >> > >> The problem is basically this: "ping hackage.haskell.org" does not > >> resolve > >> host while "ping6 hackage.haskell.org" does. Thus cabal cannot do > >> anything > >> useful on that machine. > >> > >> Do anyone have a solution for that? I was unable to find any on the > >> internet. ;) > >> _______________________________________________ > >> Haskell-Cafe mailing list > >> To (un)subscribe, modify options or view archives go to: > >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > >> Only members subscribed via the mailman list are allowed to post. > > > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mikhail.glushenkov at gmail.com Tue May 2 12:58:54 2017 From: mikhail.glushenkov at gmail.com (Mikhail Glushenkov) Date: Tue, 2 May 2017 13:58:54 +0100 Subject: [Haskell-cafe] Cabal and IPv6 In-Reply-To: References: Message-ID: Hi, On 2 May 2017 at 12:52, Serguey Zefirov wrote: > Cabal internally uses IPv4 calls/data structures, it seems. And fails. I believe that cabal-install itself has no IPv4-specific code, since all that stuff is encapsulated by the HTTP library. From [1] it looks like the HTTP library supports IPv6. > A proposition: is it even remotely good idea to replace in cabal source code > all calls to web API to invocation of curl/wget? This is how it works already when fetching over HTTPS (if you're on Windows, it can also use PowerShell as a transport method). Try changing the Hackage url in .cabal/config to https://hackage.haskell.org. [1] https://github.com/haskell/HTTP/pull/59 From sergueyz at gmail.com Tue May 2 14:53:35 2017 From: sergueyz at gmail.com (Serguey Zefirov) Date: Tue, 2 May 2017 17:53:35 +0300 Subject: [Haskell-cafe] Cabal and IPv6 In-Reply-To: References: Message-ID: 2017-05-02 15:58 GMT+03:00 Mikhail Glushenkov : > Hi, > > On 2 May 2017 at 12:52, Serguey Zefirov wrote: > > Cabal internally uses IPv4 calls/data structures, it seems. And fails. > > I believe that cabal-install itself has no IPv4-specific code, since > all that stuff is encapsulated by the HTTP library. From [1] it looks > like the HTTP library supports IPv6. > > > A proposition: is it even remotely good idea to replace in cabal source > code > > all calls to web API to invocation of curl/wget? > > This is how it works already when fetching over HTTPS (if you're on > Windows, it can also use PowerShell as a transport method). Try > changing the Hackage url in .cabal/config to > https://hackage.haskell.org. > I am at cabal 1.16 (yep, Ubuntu 14.04 LTS) and "https is not supported". Very sad. :( I think I'd go looking for side ways. > > > [1] https://github.com/haskell/HTTP/pull/59 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mikhail.glushenkov at gmail.com Tue May 2 15:09:13 2017 From: mikhail.glushenkov at gmail.com (Mikhail Glushenkov) Date: Tue, 2 May 2017 16:09:13 +0100 Subject: [Haskell-cafe] Cabal and IPv6 In-Reply-To: References: Message-ID: Hi, > I am at cabal 1.16 (yep, Ubuntu 14.04 LTS) and "https is not supported". This is an ancient version, try installing a newer one. Herbert's PPA [1] has a pre-compiled binary of cabal-install-1.24 (most recent stable release) for Trusty. [1] https://launchpad.net/~hvr/+archive/ubuntu/ghc From jo at durchholz.org Tue May 2 15:17:32 2017 From: jo at durchholz.org (Joachim Durchholz) Date: Tue, 2 May 2017 17:17:32 +0200 Subject: [Haskell-cafe] Cabal and IPv6 In-Reply-To: References: Message-ID: Am 02.05.2017 um 16:53 schrieb Serguey Zefirov: > > I am at cabal 1.16 (yep, Ubuntu 14.04 LTS) and "https is not supported". I think I just got the reminder that 14.04 has reached end-of-life, i.e. you won't be getting security fixes anymore. Upgrading to a newer OS might also simplify other software, so now you have *two* reasons to upgrade ;-) From mikhail.glushenkov at gmail.com Tue May 2 15:22:49 2017 From: mikhail.glushenkov at gmail.com (Mikhail Glushenkov) Date: Tue, 2 May 2017 16:22:49 +0100 Subject: [Haskell-cafe] Cabal and IPv6 In-Reply-To: References: Message-ID: Hi, On 2 May 2017 at 16:17, Joachim Durchholz wrote: > I think I just got the reminder that 14.04 has reached end-of-life, i.e. you > won't be getting security fixes anymore. I think you're thinking about 12.04, 14.04 is going to be supported until 2019 [1] (LTS releases are supported for five years). [1] https://www.ubuntu.com/info/release-end-of-life From ivan.miljenovic at gmail.com Wed May 3 04:56:42 2017 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Wed, 3 May 2017 14:56:42 +1000 Subject: [Haskell-cafe] ANNOUNCE: graphviz 2999.19.0.0 Message-ID: I've just released a new version of my Haskell bindings to the Graphviz graph visualisation toolkit. Note that the major version bump is solely because I had to remove what I thought was a useful feature (trying to allow you to do things like `"a" --> ["b", "c", "d"]` in Monadic graphs by automagically converting the "a" into ["a"]) turned out not to work in practice (as people will typically use this with literal values, but when combined with OverloadedStrings results in GHC getting confused as to what the type is). So unless you actually managed to use this functionality, then the API remains the same as 2999.18.* and you should just be able to bump your upper versions in your .cabal files (which you all do, right)? -- Ivan Lazar Miljenovic Ivan.Miljenovic at gmail.com http://IvanMiljenovic.wordpress.com From voldermort at hotmail.com Wed May 3 07:21:21 2017 From: voldermort at hotmail.com (Jonathon Delgado) Date: Wed, 3 May 2017 07:21:21 +0000 Subject: [Haskell-cafe] Foldable for (,) Message-ID: I sent the following post to the Beginners list a couple of weeks ago (which failed to furnish an actual concrete example that answered the question). Upon request I'm reposting it to Café: I've seen many threads, including the one going on now, about why we need to have: length (2,3) = 1 product (2,3) = 3 sum (2,3) = 3 or (True,False) = False but the justifications all go over my head. Is there a beginner-friendly explanation for why such seemingly unintuitive operations should be allowed by default? From tonymorris at gmail.com Wed May 3 08:32:31 2017 From: tonymorris at gmail.com (Tony Morris) Date: Wed, 3 May 2017 18:32:31 +1000 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: Message-ID: It's Foldable for ((,) a). It is not Foldable for any of these things: * (,) * tuples * pairs In fact, to talk about a Foldable for (,) or "tuples" is itself a kind error. There is no good English name for the type constructor ((,) a) which I suspect, along with being unfamiliar with utilising the practical purpose of types (and types of types) is the root cause of all the confusion in this discussion. Ask yourself what the length of this value is: [[1,2,3], [4,5,6]] Is it 6? What about this one: [(1, 'a'), (undefined, 77)] Is it 4? No, obviously not, which we can determine by: :kind Foldable :: (* -> *) -> Constraint :kind [] :: * -> * Therefore, there is no possible way that the Foldable instance for [] can inspect the elements (and determine that they are pairs in this case). By this method, we conclude that the length of the value is 2. It cannot be anything else, some assumptions about length itself put aside. By this ubiquitous and very practical method of reasoning, the length of any ((,) a) is not only one, but very obviously so. On 03/05/17 17:21, Jonathon Delgado wrote: > I sent the following post to the Beginners list a couple of weeks ago (which failed to furnish an actual concrete example that answered the question). Upon request I'm reposting it to Café: > > I've seen many threads, including the one going on now, about why we need to have: > > length (2,3) = 1 > product (2,3) = 3 > sum (2,3) = 3 > or (True,False) = False > > but the justifications all go over my head. Is there a beginner-friendly explanation for why such seemingly unintuitive operations should be allowed by default? > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 488 bytes Desc: OpenPGP digital signature URL: From voldermort at hotmail.com Wed May 3 08:41:43 2017 From: voldermort at hotmail.com (Jonathon Delgado) Date: Wed, 3 May 2017 08:41:43 +0000 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: , Message-ID: Thank you for your explanation, but I think I'm missing something basic. Lists can have a variable length, so it makes sense to have operations that return the length or operate over a set. As ((,) a) can only have one value, the Foldable operations appear to be redundant as well as misleading (by implying that there could be more than one value). From: Haskell-Cafe on behalf of Tony Morris Sent: 03 May 2017 08:32 To: haskell-cafe at haskell.org Subject: Re: [Haskell-cafe] Foldable for (,)   It's Foldable for ((,) a). It is not Foldable for any of these things: * (,) * tuples * pairs In fact, to talk about a Foldable for (,) or "tuples" is itself a kind error. There is no good English name for the type constructor ((,) a) which I suspect, along with being unfamiliar with utilising the practical purpose of types (and types of types) is the root cause of all the confusion in this discussion. Ask yourself what the length of this value is: [[1,2,3], [4,5,6]] Is it 6? What about this one: [(1, 'a'), (undefined, 77)] Is it 4? No, obviously not, which we can determine by: :kind Foldable :: (* -> *) -> Constraint :kind [] :: * -> * Therefore, there is no possible way that the Foldable instance for [] can inspect the elements (and determine that they are pairs in this case). By this method, we conclude that the length of the value is 2. It cannot be anything else, some assumptions about length itself put aside. By this ubiquitous and very practical method of reasoning, the length of any ((,) a) is not only one, but very obviously so. On 03/05/17 17:21, Jonathon Delgado wrote: > I sent the following post to the Beginners list a couple of weeks ago (which failed to furnish an actual concrete example that answered the question). Upon request I'm reposting it to Café: > > I've seen many threads, including the one going on now, about why we need to have: > > length (2,3) = 1 > product (2,3) = 3 > sum (2,3) = 3 > or (True,False) = False > > but the justifications all go over my head. Is there a beginner-friendly explanation for why such seemingly unintuitive operations should be allowed by default? > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Haskell-Cafe Info Page mail.haskell.org This mailing list is for the discussion of topics related to Haskell. The volume may at times be high, as the scope is broader than the main Haskell mailing list. > Only members subscribed via the mailman list are allowed to post. From cdsmith at gmail.com Wed May 3 08:44:16 2017 From: cdsmith at gmail.com (Chris Smith) Date: Wed, 3 May 2017 01:44:16 -0700 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: Message-ID: I'm also interested in Jonathon's question, so let me try to bring things back to the question. Everyone agrees that there's only one reasonable way to define this instance if it exists. But the question is: why is it defined at all? That's an easy question to answer for Functor, Applicative, and Monad. But I am having trouble giving a simple or accessible answer for Foldable. Do you know one? On Wed, May 3, 2017 at 1:32 AM, Tony Morris wrote: > It's Foldable for ((,) a). > > It is not Foldable for any of these things: > > * (,) > * tuples > * pairs > > In fact, to talk about a Foldable for (,) or "tuples" is itself a kind > error. There is no good English name for the type constructor ((,) a) > which I suspect, along with being unfamiliar with utilising the > practical purpose of types (and types of types) is the root cause of all > the confusion in this discussion. > > Ask yourself what the length of this value is: > > [[1,2,3], [4,5,6]] > > Is it 6? What about this one: > > [(1, 'a'), (undefined, 77)] > > Is it 4? No, obviously not, which we can determine by: > > :kind Foldable :: (* -> *) -> Constraint > :kind [] :: * -> * > > Therefore, there is no possible way that the Foldable instance for [] > can inspect the elements (and determine that they are pairs in this > case). By this method, we conclude that the length of the value is 2. It > cannot be anything else, some assumptions about length itself put aside. > > By this ubiquitous and very practical method of reasoning, the length of > any ((,) a) is not only one, but very obviously so. > > On 03/05/17 17:21, Jonathon Delgado wrote: > > I sent the following post to the Beginners list a couple of weeks ago > (which failed to furnish an actual concrete example that answered the > question). Upon request I'm reposting it to Café: > > > > I've seen many threads, including the one going on now, about why we > need to have: > > > > length (2,3) = 1 > > product (2,3) = 3 > > sum (2,3) = 3 > > or (True,False) = False > > > > but the justifications all go over my head. Is there a beginner-friendly > explanation for why such seemingly unintuitive operations should be allowed > by default? > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From cdsmith at gmail.com Wed May 3 08:51:44 2017 From: cdsmith at gmail.com (Chris Smith) Date: Wed, 3 May 2017 01:51:44 -0700 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: Message-ID: Replying to myself, I suppose one good answer is that whether or not you care about Foldable instances for tuples, you might care about Traversable instances, and those require Foldable as a superclass. For example, one possible specialization of `traverse` is: traverse :: (a -> IO b) -> (SideValue, a) -> IO (SideValue, b) Jonathon, I don't know how much background you're coming from, so I'd be happy to explain that in more detail if you need it. On Wed, May 3, 2017 at 1:44 AM, Chris Smith wrote: > I'm also interested in Jonathon's question, so let me try to bring things > back to the question. Everyone agrees that there's only one reasonable way > to define this instance if it exists. But the question is: why is it > defined at all? > > That's an easy question to answer for Functor, Applicative, and Monad. > But I am having trouble giving a simple or accessible answer for Foldable. > Do you know one? > > On Wed, May 3, 2017 at 1:32 AM, Tony Morris wrote: > >> It's Foldable for ((,) a). >> >> It is not Foldable for any of these things: >> >> * (,) >> * tuples >> * pairs >> >> In fact, to talk about a Foldable for (,) or "tuples" is itself a kind >> error. There is no good English name for the type constructor ((,) a) >> which I suspect, along with being unfamiliar with utilising the >> practical purpose of types (and types of types) is the root cause of all >> the confusion in this discussion. >> >> Ask yourself what the length of this value is: >> >> [[1,2,3], [4,5,6]] >> >> Is it 6? What about this one: >> >> [(1, 'a'), (undefined, 77)] >> >> Is it 4? No, obviously not, which we can determine by: >> >> :kind Foldable :: (* -> *) -> Constraint >> :kind [] :: * -> * >> >> Therefore, there is no possible way that the Foldable instance for [] >> can inspect the elements (and determine that they are pairs in this >> case). By this method, we conclude that the length of the value is 2. It >> cannot be anything else, some assumptions about length itself put aside. >> >> By this ubiquitous and very practical method of reasoning, the length of >> any ((,) a) is not only one, but very obviously so. >> >> On 03/05/17 17:21, Jonathon Delgado wrote: >> > I sent the following post to the Beginners list a couple of weeks ago >> (which failed to furnish an actual concrete example that answered the >> question). Upon request I'm reposting it to Café: >> > >> > I've seen many threads, including the one going on now, about why we >> need to have: >> > >> > length (2,3) = 1 >> > product (2,3) = 3 >> > sum (2,3) = 3 >> > or (True,False) = False >> > >> > but the justifications all go over my head. Is there a >> beginner-friendly explanation for why such seemingly unintuitive operations >> should be allowed by default? >> > _______________________________________________ >> > Haskell-Cafe mailing list >> > To (un)subscribe, modify options or view archives go to: >> > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> > Only members subscribed via the mailman list are allowed to post. >> >> >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From voldermort at hotmail.com Wed May 3 09:12:47 2017 From: voldermort at hotmail.com (Jonathon Delgado) Date: Wed, 3 May 2017 09:12:47 +0000 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: , Message-ID: Why do you want to traverse a tuple instead of fmap? i.e. what can you do with Foldable/Traversable for (,) that you can't do with Functor? My background, as you can probably guess, is beginner. From: Haskell-Cafe on behalf of Chris Smith Sent: 03 May 2017 08:51 To: Tony Morris Cc: haskell-cafe at haskell.org Subject: Re: [Haskell-cafe] Foldable for (,)   Replying to myself, I suppose one good answer is that whether or not you care about Foldable instances for tuples, you might care about Traversable instances, and those require Foldable as a superclass. For example, one possible specialization of `traverse` is:     traverse :: (a -> IO b) -> (SideValue, a) -> IO (SideValue, b) Jonathon, I don't know how much background you're coming from, so I'd be happy to explain that in more detail if you need it. On Wed, May 3, 2017 at 1:44 AM, Chris Smith wrote: I'm also interested in Jonathon's question, so let me try to bring things back to the question.  Everyone agrees that there's only one reasonable way to define this instance if it exists.  But the question is: why is it defined at all? That's an easy question to answer for Functor, Applicative, and Monad.  But I am having trouble giving a simple or accessible answer for Foldable.  Do you know one? On Wed, May 3, 2017 at 1:32 AM, Tony Morris wrote: It's Foldable for ((,) a). It is not Foldable for any of these things: * (,) * tuples * pairs In fact, to talk about a Foldable for (,) or "tuples" is itself a kind error. There is no good English name for the type constructor ((,) a) which I suspect, along with being unfamiliar with utilising the practical purpose of types (and types of types) is the root cause of all the confusion in this discussion. Ask yourself what the length of this value is: [[1,2,3], [4,5,6]] Is it 6? What about this one: [(1, 'a'), (undefined, 77)] Is it 4? No, obviously not, which we can determine by: :kind Foldable :: (* -> *) -> Constraint :kind [] :: * -> * Therefore, there is no possible way that the Foldable instance for [] can inspect the elements (and determine that they are pairs in this case). By this method, we conclude that the length of the value is 2. It cannot be anything else, some assumptions about length itself put aside. By this ubiquitous and very practical method of reasoning, the length of any ((,) a) is not only one, but very obviously so. On 03/05/17 17:21, Jonathon Delgado wrote: > I sent the following post to the Beginners list a couple of weeks ago (which failed to furnish an actual concrete example that answered the question). Upon request I'm reposting it to Café: > > I've seen many threads, including the one going on now, about why we need to have: > > length (2,3) = 1 > product (2,3) = 3 > sum (2,3) = 3 > or (True,False) = False > > but the justifications all go over my head. Is there a beginner-friendly explanation for why such seemingly unintuitive operations should be allowed by default? > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post. From tanuki at gmail.com Wed May 3 09:15:34 2017 From: tanuki at gmail.com (Theodore Lief Gannon) Date: Wed, 3 May 2017 02:15:34 -0700 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: Message-ID: An alternate question might be, why is length a class member and not simply a function? The instance itself is merely documentation of a mathematical fact; it's only a few members of that instance (which are never part of its minimum definition!) that seem confusing. I'm sure the answer to that involves optimizations available for particular structures, case in point for tuples: length = const 1 But it's worth understanding it in detail, probably. On Wed, May 3, 2017 at 1:51 AM, Chris Smith wrote: > Replying to myself, I suppose one good answer is that whether or not you > care about Foldable instances for tuples, you might care about Traversable > instances, and those require Foldable as a superclass. > > For example, one possible specialization of `traverse` is: > > traverse :: (a -> IO b) -> (SideValue, a) -> IO (SideValue, b) > > Jonathon, I don't know how much background you're coming from, so I'd be > happy to explain that in more detail if you need it. > > On Wed, May 3, 2017 at 1:44 AM, Chris Smith wrote: > >> I'm also interested in Jonathon's question, so let me try to bring things >> back to the question. Everyone agrees that there's only one reasonable way >> to define this instance if it exists. But the question is: why is it >> defined at all? >> >> That's an easy question to answer for Functor, Applicative, and Monad. >> But I am having trouble giving a simple or accessible answer for Foldable. >> Do you know one? >> >> On Wed, May 3, 2017 at 1:32 AM, Tony Morris wrote: >> >>> It's Foldable for ((,) a). >>> >>> It is not Foldable for any of these things: >>> >>> * (,) >>> * tuples >>> * pairs >>> >>> In fact, to talk about a Foldable for (,) or "tuples" is itself a kind >>> error. There is no good English name for the type constructor ((,) a) >>> which I suspect, along with being unfamiliar with utilising the >>> practical purpose of types (and types of types) is the root cause of all >>> the confusion in this discussion. >>> >>> Ask yourself what the length of this value is: >>> >>> [[1,2,3], [4,5,6]] >>> >>> Is it 6? What about this one: >>> >>> [(1, 'a'), (undefined, 77)] >>> >>> Is it 4? No, obviously not, which we can determine by: >>> >>> :kind Foldable :: (* -> *) -> Constraint >>> :kind [] :: * -> * >>> >>> Therefore, there is no possible way that the Foldable instance for [] >>> can inspect the elements (and determine that they are pairs in this >>> case). By this method, we conclude that the length of the value is 2. It >>> cannot be anything else, some assumptions about length itself put aside. >>> >>> By this ubiquitous and very practical method of reasoning, the length of >>> any ((,) a) is not only one, but very obviously so. >>> >>> On 03/05/17 17:21, Jonathon Delgado wrote: >>> > I sent the following post to the Beginners list a couple of weeks ago >>> (which failed to furnish an actual concrete example that answered the >>> question). Upon request I'm reposting it to Café: >>> > >>> > I've seen many threads, including the one going on now, about why we >>> need to have: >>> > >>> > length (2,3) = 1 >>> > product (2,3) = 3 >>> > sum (2,3) = 3 >>> > or (True,False) = False >>> > >>> > but the justifications all go over my head. Is there a >>> beginner-friendly explanation for why such seemingly unintuitive operations >>> should be allowed by default? >>> > _______________________________________________ >>> > Haskell-Cafe mailing list >>> > To (un)subscribe, modify options or view archives go to: >>> > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >>> > Only members subscribed via the mailman list are allowed to post. >>> >>> >>> >>> _______________________________________________ >>> Haskell-Cafe mailing list >>> To (un)subscribe, modify options or view archives go to: >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >>> Only members subscribed via the mailman list are allowed to post. >>> >> >> > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From cdsmith at gmail.com Wed May 3 09:32:18 2017 From: cdsmith at gmail.com (Chris Smith) Date: Wed, 3 May 2017 02:32:18 -0700 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: Message-ID: So, suppose I have a function: f :: a -> IO b and I need a function of the related type: (SideValue, a) -> IO (SideValue, b) Here, SideValue is some kind of state that I am manually threading through a bunch of computations. For instance, maybe I'm counting steps in a computation, and SideValue = Int. Whatever. In the particular case of `f`, I don't actually want to use it at all, because maybe `f` doesn't have any steps that need to be counted. But in general, maybe I'll be combining `f` with a bunch of other computations that *do* count steps. Maybe I have a list of such functions, and I want to add `f` into that list. Before I can do that, I need to get `f` into the right form, so I can compose it cleanly with everything else. I could use a combination of pattern matching and fmap, like this (using the TupleSections extension for convenience): \ (s, x) -> fmap (s,) (f x) But it's just a little cleaner to write this instead: traverse f Does that make sense? On Wed, May 3, 2017 at 2:12 AM, Jonathon Delgado wrote: > Why do you want to traverse a tuple instead of fmap? i.e. what can you do > with Foldable/Traversable for (,) that you can't do with Functor? > > My background, as you can probably guess, is beginner. > > > From: Haskell-Cafe on behalf of Chris > Smith > Sent: 03 May 2017 08:51 > To: Tony Morris > Cc: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Foldable for (,) > > > Replying to myself, I suppose one good answer is that whether or not you > care about Foldable instances for tuples, you might care about Traversable > instances, and those require Foldable as a superclass. > > > For example, one possible specialization of `traverse` is: > > > traverse :: (a -> IO b) -> (SideValue, a) -> IO (SideValue, b) > > > Jonathon, I don't know how much background you're coming from, so I'd be > happy to explain that in more detail if you need it. > > > On Wed, May 3, 2017 at 1:44 AM, Chris Smith wrote: > > I'm also interested in Jonathon's question, so let me try to bring things > back to the question. Everyone agrees that there's only one reasonable way > to define this instance if it exists. But the question is: why is it > defined at all? > > > That's an easy question to answer for Functor, Applicative, and Monad. > But I am having trouble giving a simple or accessible answer for Foldable. > Do you know one? > > > > > On Wed, May 3, 2017 at 1:32 AM, Tony Morris wrote: > It's Foldable for ((,) a). > > It is not Foldable for any of these things: > > * (,) > * tuples > * pairs > > In fact, to talk about a Foldable for (,) or "tuples" is itself a kind > error. There is no good English name for the type constructor ((,) a) > which I suspect, along with being unfamiliar with utilising the > practical purpose of types (and types of types) is the root cause of all > the confusion in this discussion. > > Ask yourself what the length of this value is: > > [[1,2,3], [4,5,6]] > > Is it 6? What about this one: > > [(1, 'a'), (undefined, 77)] > > Is it 4? No, obviously not, which we can determine by: > > :kind Foldable :: (* -> *) -> Constraint > :kind [] :: * -> * > > Therefore, there is no possible way that the Foldable instance for [] > can inspect the elements (and determine that they are pairs in this > case). By this method, we conclude that the length of the value is 2. It > cannot be anything else, some assumptions about length itself put aside. > > By this ubiquitous and very practical method of reasoning, the length of > any ((,) a) is not only one, but very obviously so. > > > > On 03/05/17 17:21, Jonathon Delgado wrote: > > I sent the following post to the Beginners list a couple of weeks ago > (which failed to furnish an actual concrete example that answered the > question). Upon request I'm reposting it to Café: > > > > I've seen many threads, including the one going on now, about why we > need to have: > > > > length (2,3) = 1 > > product (2,3) = 3 > > sum (2,3) = 3 > > or (True,False) = False > > > > but the justifications all go over my head. Is there a beginner-friendly > explanation for why such seemingly unintuitive operations should be allowed > by default? > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From olshanskydr at gmail.com Wed May 3 09:34:30 2017 From: olshanskydr at gmail.com (Dmitry Olshansky) Date: Wed, 3 May 2017 12:34:30 +0300 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: Message-ID: Foldable is required tor datatype to be a Traversable: class (Functor t, Foldable t) => Traversable (t :: * -> *) ((,) a) is Functor. To be Traversable it has to be Foldable. If ((,) a) is Traversable then we can write: sequence (1, Just 2) -- == Just (1,2) sequence (1, Nothing) -- == Nothing There could be other useful classes or functions which required Foldable. An other side, a tuple (with parameterized second part) can be a part of complex datatype and possibly we need Foldable or Traversable instance for that type. If someone inhabits to think about tuple as a Functor, he/she can think about tuple as Foldable and Traversable as well: fmap (+1) (1,2) == (1,3) foldMap (+1) (1,2) == 3 There are other datatypes with similar Foldable instances. I mean a least Identity. length (Identity [1,2,3]) == 1 2017-05-03 11:41 GMT+03:00 Jonathon Delgado : > Thank you for your explanation, but I think I'm missing something basic. > Lists can have a variable length, so it makes sense to have operations that > return the length or operate over a set. As ((,) a) can only have one > value, the Foldable operations appear to be redundant as well as misleading > (by implying that there could be more than one value). > > From: Haskell-Cafe on behalf of Tony > Morris > Sent: 03 May 2017 08:32 > To: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Foldable for (,) > > It's Foldable for ((,) a). > > It is not Foldable for any of these things: > > * (,) > * tuples > * pairs > > In fact, to talk about a Foldable for (,) or "tuples" is itself a kind > error. There is no good English name for the type constructor ((,) a) > which I suspect, along with being unfamiliar with utilising the > practical purpose of types (and types of types) is the root cause of all > the confusion in this discussion. > > Ask yourself what the length of this value is: > > [[1,2,3], [4,5,6]] > > Is it 6? What about this one: > > [(1, 'a'), (undefined, 77)] > > Is it 4? No, obviously not, which we can determine by: > > :kind Foldable :: (* -> *) -> Constraint > :kind [] :: * -> * > > Therefore, there is no possible way that the Foldable instance for [] > can inspect the elements (and determine that they are pairs in this > case). By this method, we conclude that the length of the value is 2. It > cannot be anything else, some assumptions about length itself put aside. > > By this ubiquitous and very practical method of reasoning, the length of > any ((,) a) is not only one, but very obviously so. > > On 03/05/17 17:21, Jonathon Delgado wrote: > > I sent the following post to the Beginners list a couple of weeks ago > (which failed to furnish an actual concrete example that answered the > question). Upon request I'm reposting it to Café: > > > > I've seen many threads, including the one going on now, about why we > need to have: > > > > length (2,3) = 1 > > product (2,3) = 3 > > sum (2,3) = 3 > > or (True,False) = False > > > > but the justifications all go over my head. Is there a beginner-friendly > explanation for why such seemingly unintuitive operations should be allowed > by default? > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > > Haskell-Cafe Info Page > mail.haskell.org > This mailing list is for the discussion of topics related to Haskell. The > volume may at times be high, as the scope is broader than the main Haskell > mailing list. > > > Only members subscribed via the mailman list are allowed to post. > > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From monkleyon at gmail.com Wed May 3 09:43:10 2017 From: monkleyon at gmail.com (MarLinn) Date: Wed, 3 May 2017 11:43:10 +0200 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: Message-ID: A different way to think about it is this: Given any kind of n-tuples that is already filled at any set of n-1 places, there are unique instances for the whole hierarchy (from Functor up to Traversable). For example there is – theoretically – a hierarchy of instances for the tuples (a,b,_,c,d,e). Why isn't it defined? Because 1., we let ourselves be restrained by the linearity of text that "forces" us to define instances in terms of an arbitrary choice of order of arguments. 2., because the longer the tuples, the less we need it, and 3., because it's easier to wing it for the small tuples than to change the language. Also 4., in practice, lens. On 2017-05-03 10:41, Jonathon Delgado wrote: > Thank you for your explanation, but I think I'm missing something basic. Lists can have a variable length, so it makes sense to have operations that return the length or operate over a set. As ((,) a) can only have one value, the Foldable operations appear to be redundant as well as misleading (by implying that there could be more than one value). > > From: Haskell-Cafe on behalf of Tony Morris > Sent: 03 May 2017 08:32 > To: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Foldable for (,) > > It's Foldable for ((,) a). > > It is not Foldable for any of these things: > > * (,) > * tuples > * pairs > > In fact, to talk about a Foldable for (,) or "tuples" is itself a kind > error. There is no good English name for the type constructor ((,) a) > which I suspect, along with being unfamiliar with utilising the > practical purpose of types (and types of types) is the root cause of all > the confusion in this discussion. > > Ask yourself what the length of this value is: > > [[1,2,3], [4,5,6]] > > Is it 6? What about this one: > > [(1, 'a'), (undefined, 77)] > > Is it 4? No, obviously not, which we can determine by: > > :kind Foldable :: (* -> *) -> Constraint > :kind [] :: * -> * > > Therefore, there is no possible way that the Foldable instance for [] > can inspect the elements (and determine that they are pairs in this > case). By this method, we conclude that the length of the value is 2. It > cannot be anything else, some assumptions about length itself put aside. > > By this ubiquitous and very practical method of reasoning, the length of > any ((,) a) is not only one, but very obviously so. > > On 03/05/17 17:21, Jonathon Delgado wrote: >> I sent the following post to the Beginners list a couple of weeks ago (which failed to furnish an actual concrete example that answered the question). Upon request I'm reposting it to Café: >> >> I've seen many threads, including the one going on now, about why we need to have: >> >> length (2,3) = 1 >> product (2,3) = 3 >> sum (2,3) = 3 >> or (True,False) = False >> >> but the justifications all go over my head. Is there a beginner-friendly explanation for why such seemingly unintuitive operations should be allowed by default? >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Haskell-Cafe Info Page > mail.haskell.org > This mailing list is for the discussion of topics related to Haskell. The volume may at times be high, as the scope is broader than the main Haskell mailing list. > >> Only members subscribed via the mailman list are allowed to post. > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From olshanskydr at gmail.com Wed May 3 09:53:38 2017 From: olshanskydr at gmail.com (Dmitry Olshansky) Date: Wed, 3 May 2017 12:53:38 +0300 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: Message-ID: With fmap you can only change all values in some "container". With Foldable you can "fold" it, i.e. calculate some "scalar" result. With Traversable you can "change order of two containers": > sequenceA [[1,2,3],[4,5]] [[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]] > sequenceA ("test",[2,3,4]) [("test",2),("test",3),("test",4)] > sequenceA ("test",([1,2,3],[4,5,6])) ([1,2,3],("test",[4,5,6])) 2017-05-03 12:12 GMT+03:00 Jonathon Delgado : > Why do you want to traverse a tuple instead of fmap? i.e. what can you do > with Foldable/Traversable for (,) that you can't do with Functor? > > My background, as you can probably guess, is beginner. > > > From: Haskell-Cafe on behalf of Chris > Smith > Sent: 03 May 2017 08:51 > To: Tony Morris > Cc: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Foldable for (,) > > > Replying to myself, I suppose one good answer is that whether or not you > care about Foldable instances for tuples, you might care about Traversable > instances, and those require Foldable as a superclass. > > > For example, one possible specialization of `traverse` is: > > > traverse :: (a -> IO b) -> (SideValue, a) -> IO (SideValue, b) > > > Jonathon, I don't know how much background you're coming from, so I'd be > happy to explain that in more detail if you need it. > > > On Wed, May 3, 2017 at 1:44 AM, Chris Smith wrote: > > I'm also interested in Jonathon's question, so let me try to bring things > back to the question. Everyone agrees that there's only one reasonable way > to define this instance if it exists. But the question is: why is it > defined at all? > > > That's an easy question to answer for Functor, Applicative, and Monad. > But I am having trouble giving a simple or accessible answer for Foldable. > Do you know one? > > > > > On Wed, May 3, 2017 at 1:32 AM, Tony Morris wrote: > It's Foldable for ((,) a). > > It is not Foldable for any of these things: > > * (,) > * tuples > * pairs > > In fact, to talk about a Foldable for (,) or "tuples" is itself a kind > error. There is no good English name for the type constructor ((,) a) > which I suspect, along with being unfamiliar with utilising the > practical purpose of types (and types of types) is the root cause of all > the confusion in this discussion. > > Ask yourself what the length of this value is: > > [[1,2,3], [4,5,6]] > > Is it 6? What about this one: > > [(1, 'a'), (undefined, 77)] > > Is it 4? No, obviously not, which we can determine by: > > :kind Foldable :: (* -> *) -> Constraint > :kind [] :: * -> * > > Therefore, there is no possible way that the Foldable instance for [] > can inspect the elements (and determine that they are pairs in this > case). By this method, we conclude that the length of the value is 2. It > cannot be anything else, some assumptions about length itself put aside. > > By this ubiquitous and very practical method of reasoning, the length of > any ((,) a) is not only one, but very obviously so. > > > > On 03/05/17 17:21, Jonathon Delgado wrote: > > I sent the following post to the Beginners list a couple of weeks ago > (which failed to furnish an actual concrete example that answered the > question). Upon request I'm reposting it to Café: > > > > I've seen many threads, including the one going on now, about why we > need to have: > > > > length (2,3) = 1 > > product (2,3) = 3 > > sum (2,3) = 3 > > or (True,False) = False > > > > but the justifications all go over my head. Is there a beginner-friendly > explanation for why such seemingly unintuitive operations should be allowed > by default? > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From voldermort at hotmail.com Wed May 3 09:56:46 2017 From: voldermort at hotmail.com (Jonathon Delgado) Date: Wed, 3 May 2017 09:56:46 +0000 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: , Message-ID: OK, I understand why Traversable is useful here - thank you Chris and Dmitry! The next question is why Traversable requires Foldable. I looked at the source, and couldn't see where Foldable is being used, other than as a constraint on Traversable. To put the question differently, what would fail to compile if this constraint was removed? From: Dmitry Olshansky Sent: 03 May 2017 09:53 To: Jonathon Delgado Cc: haskell-cafe at haskell.org Subject: Re: [Haskell-cafe] Foldable for (,)   With fmap you can only change all values in some "container". With Foldable you can "fold" it, i.e. calculate some "scalar" result. With Traversable you can "change order of two containers": > sequenceA [[1,2,3],[4,5]] [[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]] > sequenceA ("test",[2,3,4]) [("test",2),("test",3),("test",4)] > sequenceA ("test",([1,2,3],[4,5,6])) ([1,2,3],("test",[4,5,6])) 2017-05-03 12:12 GMT+03:00 Jonathon Delgado : Why do you want to traverse a tuple instead of fmap? i.e. what can you do with Foldable/Traversable for (,) that you can't do with Functor? My background, as you can probably guess, is beginner. From: Haskell-Cafe on behalf of Chris Smith Sent: 03 May 2017 08:51 To: Tony Morris Cc: haskell-cafe at haskell.org Subject: Re: [Haskell-cafe] Foldable for (,)   Replying to myself, I suppose one good answer is that whether or not you care about Foldable instances for tuples, you might care about Traversable instances, and those require Foldable as a superclass. For example, one possible specialization of `traverse` is:     traverse :: (a -> IO b) -> (SideValue, a) -> IO (SideValue, b) Jonathon, I don't know how much background you're coming from, so I'd be happy to explain that in more detail if you need it. On Wed, May 3, 2017 at 1:44 AM, Chris Smith  wrote: I'm also interested in Jonathon's question, so let me try to bring things back to the question.  Everyone agrees that there's only one reasonable way to define this instance if it exists.  But the question is: why is it defined at all? That's an easy question to answer for Functor, Applicative, and Monad.  But I am having trouble giving a simple or accessible answer for Foldable.  Do you know one? On Wed, May 3, 2017 at 1:32 AM, Tony Morris  wrote:  It's Foldable for ((,) a). It is not Foldable for any of these things: * (,) * tuples * pairs In fact, to talk about a Foldable for (,) or "tuples" is itself a kind error. There is no good English name for the type constructor ((,) a) which I suspect, along with being unfamiliar with utilising the practical purpose of types (and types of types) is the root cause of all the confusion in this discussion. Ask yourself what the length of this value is: [[1,2,3], [4,5,6]] Is it 6? What about this one: [(1, 'a'), (undefined, 77)] Is it 4? No, obviously not, which we can determine by: :kind Foldable :: (* -> *) -> Constraint :kind [] :: * -> * Therefore, there is no possible way that the Foldable instance for [] can inspect the elements (and determine that they are pairs in this case). By this method, we conclude that the length of the value is 2. It cannot be anything else, some assumptions about length itself put aside. By this ubiquitous and very practical method of reasoning, the length of any ((,) a) is not only one, but very obviously so. On 03/05/17 17:21, Jonathon Delgado wrote: > I sent the following post to the Beginners list a couple of weeks ago (which failed to furnish an actual concrete example that answered the question). Upon request I'm reposting it to Café: > > I've seen many threads, including the one going on now, about why we need to have: > > length (2,3) = 1 > product (2,3) = 3 > sum (2,3) = 3 > or (True,False) = False > > but the justifications all go over my head. Is there a beginner-friendly explanation for why such seemingly unintuitive operations should be allowed by default? > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: >  http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post. From olshanskydr at gmail.com Wed May 3 10:47:44 2017 From: olshanskydr at gmail.com (Dmitry Olshansky) Date: Wed, 3 May 2017 13:47:44 +0300 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: Message-ID: Look how instance for List is defined. > instance Traversable [] where {-# INLINE traverse #-} -- so that traverse can fuse traverse f = List.foldr cons_f (pure []) where cons_f x ys = (:) <$> f x <*> ys > > It uses List.foldr. Many other instances do the same. Functions in all instances of class should have the same signatures. So we have to add Foldable constraint to the class. Of cause we can implement 'foldr' internaly in 'traverse' if needed (as well as fmap). But this is not so good and more important that in this case we don't know how to derive Traversable instances automatically. So the answer - many instances wouldn't compile and DeriveTraversable wouldn't work. 2017-05-03 12:56 GMT+03:00 Jonathon Delgado : > OK, I understand why Traversable is useful here - thank you Chris and > Dmitry! > > The next question is why Traversable requires Foldable. I looked at the > source, and couldn't see where Foldable is being used, other than as a > constraint on Traversable. To put the question differently, what would fail > to compile if this constraint was removed? > > > > From: Dmitry Olshansky > Sent: 03 May 2017 09:53 > To: Jonathon Delgado > Cc: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Foldable for (,) > > > > > > With fmap you can only change all values in some "container". > > With Foldable you can "fold" it, i.e. calculate some "scalar" result. > > With Traversable you can "change order of two containers": > > sequenceA [[1,2,3],[4,5]] > [[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]] > > sequenceA ("test",[2,3,4]) > [("test",2),("test",3),("test",4)] > > sequenceA ("test",([1,2,3],[4,5,6])) > ([1,2,3],("test",[4,5,6])) > > > > > > 2017-05-03 12:12 GMT+03:00 Jonathon Delgado : > Why do you want to traverse a tuple instead of fmap? i.e. what can you do > with Foldable/Traversable for (,) that you can't do with Functor? > > My background, as you can probably guess, is beginner. > > > From: Haskell-Cafe on behalf of Chris > Smith > Sent: 03 May 2017 08:51 > To: Tony Morris > Cc: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Foldable for (,) > > > > > Replying to myself, I suppose one good answer is that whether or not you > care about Foldable instances for tuples, you might care about Traversable > instances, and those require Foldable as a superclass. > > > For example, one possible specialization of `traverse` is: > > > traverse :: (a -> IO b) -> (SideValue, a) -> IO (SideValue, b) > > > Jonathon, I don't know how much background you're coming from, so I'd be > happy to explain that in more detail if you need it. > > > On Wed, May 3, 2017 at 1:44 AM, Chris Smith wrote: > > I'm also interested in Jonathon's question, so let me try to bring things > back to the question. Everyone agrees that there's only one reasonable way > to define this instance if it exists. But the question is: why is it > defined at all? > > > That's an easy question to answer for Functor, Applicative, and Monad. > But I am having trouble giving a simple or accessible answer for Foldable. > Do you know one? > > > > > On Wed, May 3, 2017 at 1:32 AM, Tony Morris wrote: > It's Foldable for ((,) a). > > It is not Foldable for any of these things: > > * (,) > * tuples > * pairs > > In fact, to talk about a Foldable for (,) or "tuples" is itself a kind > error. There is no good English name for the type constructor ((,) a) > which I suspect, along with being unfamiliar with utilising the > practical purpose of types (and types of types) is the root cause of all > the confusion in this discussion. > > Ask yourself what the length of this value is: > > [[1,2,3], [4,5,6]] > > Is it 6? What about this one: > > [(1, 'a'), (undefined, 77)] > > Is it 4? No, obviously not, which we can determine by: > > :kind Foldable :: (* -> *) -> Constraint > :kind [] :: * -> * > > Therefore, there is no possible way that the Foldable instance for [] > can inspect the elements (and determine that they are pairs in this > case). By this method, we conclude that the length of the value is 2. It > cannot be anything else, some assumptions about length itself put aside. > > By this ubiquitous and very practical method of reasoning, the length of > any ((,) a) is not only one, but very obviously so. > > > > On 03/05/17 17:21, Jonathon Delgado wrote: > > I sent the following post to the Beginners list a couple of weeks ago > (which failed to furnish an actual concrete example that answered the > question). Upon request I'm reposting it to Café: > > > > I've seen many threads, including the one going on now, about why we > need to have: > > > > length (2,3) = 1 > > product (2,3) = 3 > > sum (2,3) = 3 > > or (True,False) = False > > > > but the justifications all go over my head. Is there a beginner-friendly > explanation for why such seemingly unintuitive operations should be allowed > by default? > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From voldermort at hotmail.com Wed May 3 11:17:12 2017 From: voldermort at hotmail.com (Jonathon Delgado) Date: Wed, 3 May 2017 11:17:12 +0000 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: , Message-ID: List.foldr has signature (a -> b -> b) -> b -> [a] -> b, i.e. an actual list? How is this effected by the Foldable constraint? From: Dmitry Olshansky Sent: 03 May 2017 10:47 To: Jonathon Delgado Cc: haskell-cafe at haskell.org Subject: Re: [Haskell-cafe] Foldable for (,)   Look how instance for List is defined. instance Traversable [] where {-# INLINE traverse #-} -- so that traverse can fuse traverse f = List.foldr cons_f (pure []) where cons_f x ys = (:) <$> f x <*> ys It uses List.foldr. Many other instances do the same. Functions in all instances of class should have the same signatures. So we have to add Foldable constraint to the class. Of cause we can implement 'foldr' internaly in 'traverse' if needed (as well as fmap). But this is not so good and more important that in this case we don't know how to derive Traversable instances automatically. So the answer - many instances wouldn't compile and DeriveTraversable wouldn't work. 2017-05-03 12:56 GMT+03:00 Jonathon Delgado : OK, I understand why Traversable is useful here - thank you Chris and Dmitry! The next question is why Traversable requires Foldable. I looked at the source, and couldn't see where Foldable is being used, other than as a constraint on Traversable. To put the question differently, what would fail to compile if this constraint was removed? From: Dmitry Olshansky Sent: 03 May 2017 09:53 To: Jonathon Delgado Cc: haskell-cafe at haskell.org Subject: Re: [Haskell-cafe] Foldable for (,)   With fmap you can only change all values in some "container".  With Foldable you can "fold" it, i.e. calculate some "scalar" result.  With Traversable you can "change order of two containers": > sequenceA [[1,2,3],[4,5]] [[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]] > sequenceA ("test",[2,3,4]) [("test",2),("test",3),("test",4)] > sequenceA ("test",([1,2,3],[4,5,6])) ([1,2,3],("test",[4,5,6])) 2017-05-03 12:12 GMT+03:00 Jonathon Delgado  :  Why do you want to traverse a tuple instead of fmap? i.e. what can you do with Foldable/Traversable for (,) that you can't do with Functor? My background, as you can probably guess, is beginner. From: Haskell-Cafe on behalf of Chris Smith Sent: 03 May 2017 08:51 To: Tony Morris Cc: haskell-cafe at haskell.org Subject: Re: [Haskell-cafe] Foldable for (,)   Replying to myself, I suppose one good answer is that whether or not you care about Foldable instances for tuples, you might care about Traversable instances, and those require Foldable as a superclass. For example, one possible specialization of `traverse` is:     traverse :: (a -> IO b) -> (SideValue, a) -> IO (SideValue, b) Jonathon, I don't know how much background you're coming from, so I'd be happy to explain that in more detail if you need it. On Wed, May 3, 2017 at 1:44 AM, Chris Smith  wrote: I'm also interested in Jonathon's question, so let me try to bring things back to the question.  Everyone agrees that there's only one reasonable way to define this instance if it exists.  But the question is: why is it defined at all? That's an easy question to answer for Functor, Applicative, and Monad.  But I am having trouble giving a simple or accessible answer for Foldable.  Do you know one? On Wed, May 3, 2017 at 1:32 AM, Tony Morris  wrote:  It's Foldable for ((,) a). It is not Foldable for any of these things: * (,) * tuples * pairs In fact, to talk about a Foldable for (,) or "tuples" is itself a kind error. There is no good English name for the type constructor ((,) a) which I suspect, along with being unfamiliar with utilising the practical purpose of types (and types of types) is the root cause of all the confusion in this discussion. Ask yourself what the length of this value is: [[1,2,3], [4,5,6]] Is it 6? What about this one: [(1, 'a'), (undefined, 77)] Is it 4? No, obviously not, which we can determine by: :kind Foldable :: (* -> *) -> Constraint :kind [] :: * -> * Therefore, there is no possible way that the Foldable instance for [] can inspect the elements (and determine that they are pairs in this case). By this method, we conclude that the length of the value is 2. It cannot be anything else, some assumptions about length itself put aside. By this ubiquitous and very practical method of reasoning, the length of any ((,) a) is not only one, but very obviously so. On 03/05/17 17:21, Jonathon Delgado wrote: > I sent the following post to the Beginners list a couple of weeks ago (which failed to furnish an actual concrete example that answered the question). Upon request I'm reposting it to Café: > > I've seen many threads, including the one going on now, about why we need to have: > > length (2,3) = 1 > product (2,3) = 3 > sum (2,3) = 3 > or (True,False) = False > > but the justifications all go over my head. Is there a beginner-friendly explanation for why such seemingly unintuitive operations should be allowed by default? > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: >   http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post. From tonymorris at gmail.com Wed May 3 11:21:51 2017 From: tonymorris at gmail.com (Tony Morris) Date: Wed, 3 May 2017 21:21:51 +1000 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: Message-ID: https://i.imgur.com/A2enuhq.png On 03/05/17 21:17, Jonathon Delgado wrote: > List.foldr has signature (a -> b -> b) -> b -> [a] -> b, i.e. an actual list? How is this effected by the Foldable constraint? > > > > From: Dmitry Olshansky > Sent: 03 May 2017 10:47 > To: Jonathon Delgado > Cc: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Foldable for (,) > > > > Look how instance for List is defined. > > instance Traversable [] where {-# INLINE traverse #-} -- so that traverse can fuse traverse f = List.foldr cons_f (pure []) where cons_f x ys = (:) <$> f x <*> ys It uses List.foldr. Many other instances do the same. > Functions in all instances of class should have the same signatures. So we have to add Foldable constraint to the class. > Of cause we can implement 'foldr' internaly in 'traverse' if needed (as well as fmap). > But this is not so good and more important that in this case we don't know how to derive Traversable instances automatically. > > So the answer - many instances wouldn't compile and DeriveTraversable wouldn't work. > > > > 2017-05-03 12:56 GMT+03:00 Jonathon Delgado : > OK, I understand why Traversable is useful here - thank you Chris and Dmitry! > > The next question is why Traversable requires Foldable. I looked at the source, and couldn't see where Foldable is being used, other than as a constraint on Traversable. To put the question differently, what would fail to compile if this constraint was removed? > > > > From: Dmitry Olshansky > Sent: 03 May 2017 09:53 > To: Jonathon Delgado > > > Cc: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Foldable for (,) > > > > > > With fmap you can only change all values in some "container". > > With Foldable you can "fold" it, i.e. calculate some "scalar" result. > > With Traversable you can "change order of two containers": >> sequenceA [[1,2,3],[4,5]] > [[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]] >> sequenceA ("test",[2,3,4]) > [("test",2),("test",3),("test",4)] >> sequenceA ("test",([1,2,3],[4,5,6])) > ([1,2,3],("test",[4,5,6])) > > > > > > 2017-05-03 12:12 GMT+03:00 Jonathon Delgado : > Why do you want to traverse a tuple instead of fmap? i.e. what can you do with Foldable/Traversable for (,) that you can't do with Functor? > > My background, as you can probably guess, is beginner. > > > From: Haskell-Cafe on behalf of Chris Smith > Sent: 03 May 2017 08:51 > To: Tony Morris > Cc: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Foldable for (,) > > > > > Replying to myself, I suppose one good answer is that whether or not you care about Foldable instances for tuples, you might care about Traversable instances, and those require Foldable as a superclass. > > > For example, one possible specialization of `traverse` is: > > > traverse :: (a -> IO b) -> (SideValue, a) -> IO (SideValue, b) > > > Jonathon, I don't know how much background you're coming from, so I'd be happy to explain that in more detail if you need it. > > > On Wed, May 3, 2017 at 1:44 AM, Chris Smith wrote: > > I'm also interested in Jonathon's question, so let me try to bring things back to the question. Everyone agrees that there's only one reasonable way to define this instance if it exists. But the question is: why is it defined at all? > > > That's an easy question to answer for Functor, Applicative, and Monad. But I am having trouble giving a simple or accessible answer for Foldable. Do you know one? > > > > > On Wed, May 3, 2017 at 1:32 AM, Tony Morris wrote: > It's Foldable for ((,) a). > > It is not Foldable for any of these things: > > * (,) > * tuples > * pairs > > In fact, to talk about a Foldable for (,) or "tuples" is itself a kind > error. There is no good English name for the type constructor ((,) a) > which I suspect, along with being unfamiliar with utilising the > practical purpose of types (and types of types) is the root cause of all > the confusion in this discussion. > > Ask yourself what the length of this value is: > > [[1,2,3], [4,5,6]] > > Is it 6? What about this one: > > [(1, 'a'), (undefined, 77)] > > Is it 4? No, obviously not, which we can determine by: > > :kind Foldable :: (* -> *) -> Constraint > :kind [] :: * -> * > > Therefore, there is no possible way that the Foldable instance for [] > can inspect the elements (and determine that they are pairs in this > case). By this method, we conclude that the length of the value is 2. It > cannot be anything else, some assumptions about length itself put aside. > > By this ubiquitous and very practical method of reasoning, the length of > any ((,) a) is not only one, but very obviously so. > > > > On 03/05/17 17:21, Jonathon Delgado wrote: >> I sent the following post to the Beginners list a couple of weeks ago (which failed to furnish an actual concrete example that answered the question). Upon request I'm reposting it to Café: >> >> I've seen many threads, including the one going on now, about why we need to have: >> >> length (2,3) = 1 >> product (2,3) = 3 >> sum (2,3) = 3 >> or (True,False) = False >> >> but the justifications all go over my head. Is there a beginner-friendly explanation for why such seemingly unintuitive operations should be allowed by default? >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 488 bytes Desc: OpenPGP digital signature URL: From voldermort at hotmail.com Wed May 3 11:34:55 2017 From: voldermort at hotmail.com (Jonathon Delgado) Date: Wed, 3 May 2017 11:34:55 +0000 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: , Message-ID: Interesting, that's not the one linked to from Dmitry's code. In any case, is this correct? 1) Traversable is useful for all containers, including ones which can only hold a single value, such as (,) a. 2) The traversable definition for containers which can hold multiple versions requires Foldable. 3) So Traversable has to depend on Foldable. 4) So singleton containers also have to implement Foldable, even when it doesn't really make sense to do so. Is there some kind of refactoring which would "fix" this, other than two unrelated Traversable classes? I understand that it might be impractical to refactor a widely-used standard library, but I would be interested in how such a situation could be avoided when starting from scratch. From: Haskell-Cafe on behalf of Tony Morris Sent: 03 May 2017 11:21 To: haskell-cafe at haskell.org Subject: Re: [Haskell-cafe] Foldable for (,)   https://i.imgur.com/A2enuhq.png On 03/05/17 21:17, Jonathon Delgado wrote: > List.foldr has signature (a -> b -> b) -> b -> [a] -> b, i.e. an actual list? How is this effected by the Foldable constraint? > > > > From: Dmitry Olshansky > Sent: 03 May 2017 10:47 > To: Jonathon Delgado > Cc: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Foldable for (,) >   > > > Look how instance for List is defined. > > instance Traversable [] where     {-# INLINE traverse #-} -- so that traverse can fuse     traverse f = List.foldr cons_f (pure [])       where cons_f x ys = (:) <$> f x <*> ys It uses List.foldr. Many other instances do the same. > Functions in all instances of class should have the same signatures. So we have to add Foldable constraint to the class. > Of cause we can implement 'foldr' internaly in 'traverse' if needed (as well as fmap). > But this is not so good and more important that in this case we don't know how to derive Traversable instances automatically. > > So the answer - many instances wouldn't compile and DeriveTraversable wouldn't work. >   > > > 2017-05-03 12:56 GMT+03:00 Jonathon Delgado  : >  OK, I understand why Traversable is useful here - thank you Chris and Dmitry! > > The next question is why Traversable requires Foldable. I looked at the source, and couldn't see where Foldable is being used, other than as a constraint on Traversable. To put the question differently, what would fail to compile if this constraint was removed? > > > > From: Dmitry Olshansky > Sent: 03 May 2017 09:53 > To: Jonathon Delgado > > > Cc: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Foldable for (,) >  > > > > > With fmap you can only change all values in some "container". > >  With Foldable you can "fold" it, i.e. calculate some "scalar" result. > >  With Traversable you can "change order of two containers": >> sequenceA [[1,2,3],[4,5]] > [[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]] >> sequenceA ("test",[2,3,4]) > [("test",2),("test",3),("test",4)] >> sequenceA ("test",([1,2,3],[4,5,6])) > ([1,2,3],("test",[4,5,6])) > > > > > > 2017-05-03 12:12 GMT+03:00 Jonathon Delgado  : >  Why do you want to traverse a tuple instead of fmap? i.e. what can you do with Foldable/Traversable for (,) that you can't do with Functor? > > My background, as you can probably guess, is beginner. > > > From: Haskell-Cafe on behalf of Chris Smith > Sent: 03 May 2017 08:51 > To: Tony Morris > Cc: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Foldable for (,) >  > > > > Replying to myself, I suppose one good answer is that whether or not you care about Foldable instances for tuples, you might care about Traversable instances, and those require Foldable as a superclass. > > > For example, one possible specialization of `traverse` is: > > >     traverse :: (a -> IO b) -> (SideValue, a) -> IO (SideValue, b) > > > Jonathon, I don't know how much background you're coming from, so I'd be happy to explain that in more detail if you need it. > > > On Wed, May 3, 2017 at 1:44 AM, Chris Smith  wrote: > > I'm also interested in Jonathon's question, so let me try to bring things back to the question.  Everyone agrees that there's only one reasonable way to define this instance if it exists.  But the question is: why is it defined at all? > > > That's an easy question to answer for Functor, Applicative, and Monad.  But I am having trouble giving a simple or accessible answer for Foldable.  Do you know one? > > > > > On Wed, May 3, 2017 at 1:32 AM, Tony Morris  wrote: >  It's Foldable for ((,) a). > > It is not Foldable for any of these things: > > * (,) > * tuples > * pairs > > In fact, to talk about a Foldable for (,) or "tuples" is itself a kind > error. There is no good English name for the type constructor ((,) a) > which I suspect, along with being unfamiliar with utilising the > practical purpose of types (and types of types) is the root cause of all > the confusion in this discussion. > > Ask yourself what the length of this value is: > > [[1,2,3], [4,5,6]] > > Is it 6? What about this one: > > [(1, 'a'), (undefined, 77)] > > Is it 4? No, obviously not, which we can determine by: > > :kind Foldable :: (* -> *) -> Constraint > :kind [] :: * -> * > > Therefore, there is no possible way that the Foldable instance for [] > can inspect the elements (and determine that they are pairs in this > case). By this method, we conclude that the length of the value is 2. It > cannot be anything else, some assumptions about length itself put aside. > > By this ubiquitous and very practical method of reasoning, the length of > any ((,) a) is not only one, but very obviously so. > > > > On 03/05/17 17:21, Jonathon Delgado wrote: >> I sent the following post to the Beginners list a couple of weeks ago (which failed to furnish an actual concrete example that answered the question). Upon request I'm reposting it to Café: >> >> I've seen many threads, including the one going on now, about why we need to have: >> >> length (2,3) = 1 >> product (2,3) = 3 >> sum (2,3) = 3 >> or (True,False) = False >> >> but the justifications all go over my head. Is there a beginner-friendly explanation for why such seemingly unintuitive operations should be allowed by default? >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >>     http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Haskell-Cafe Info Page mail.haskell.org This mailing list is for the discussion of topics related to Haskell. The volume may at times be high, as the scope is broader than the main Haskell mailing list. >> Only members subscribed via the mailman list are allowed to post. > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Haskell-Cafe Info Page mail.haskell.org This mailing list is for the discussion of topics related to Haskell. The volume may at times be high, as the scope is broader than the main Haskell mailing list. > Only members subscribed via the mailman list are allowed to post. > > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post.   >     > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. https://i.imgur.com/A2enuhq.png From monkleyon at gmail.com Wed May 3 11:56:52 2017 From: monkleyon at gmail.com (MarLinn) Date: Wed, 3 May 2017 13:56:52 +0200 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: Message-ID: <66f63099-59ba-3aac-74fb-5d0f83ebf1e5@gmail.com> It's a nice challenge to come up with datatypes that could be Traversable but not Foldable. First of all, you can think of Traversable as an extension of Functor. Instead of only mapping over the structure with a pure function, you can now also map over it with a "functorial function" (a -> f b) (I don't know of a better name, so I'm inventing one.) What that means is to have a Traversable structure, you need to have the ability to touch every element. If you can touch every element, why would you not be able to feed them all into a folding function? Only a few possible anwers come to mind for me: 1. There might be no obvious ordering. But in practice, you just invent one. 2. The structure might be infinite, so folding would never succeed. But laziness ftw. 3. Generalizing the previous answer, the structure might be computed ad-hoc and contain fixed points. That alone might not suffice, but it sounds like a more interesting starting point. 4. Generalizing a bit differently, the structure might be computed ad-hoc… because it's IO. IO surely can't be Foldable. But could it be Traversable? Well… no actually, because order is important. So can you come up with a structure that is computed ad-hoc, that contains fixed points, and where ordering is unimportant? Good luck. Cheers. On 2017-05-03 11:56, Jonathon Delgado wrote: > OK, I understand why Traversable is useful here - thank you Chris and Dmitry! > > The next question is why Traversable requires Foldable. I looked at the source, and couldn't see where Foldable is being used, other than as a constraint on Traversable. To put the question differently, what would fail to compile if this constraint was removed? > > > > From: Dmitry Olshansky > Sent: 03 May 2017 09:53 > To: Jonathon Delgado > Cc: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Foldable for (,) > > > > > > With fmap you can only change all values in some "container". > > With Foldable you can "fold" it, i.e. calculate some "scalar" result. > > With Traversable you can "change order of two containers": >> sequenceA [[1,2,3],[4,5]] > [[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]] >> sequenceA ("test",[2,3,4]) > [("test",2),("test",3),("test",4)] >> sequenceA ("test",([1,2,3],[4,5,6])) > ([1,2,3],("test",[4,5,6])) > > > > > > 2017-05-03 12:12 GMT+03:00 Jonathon Delgado : > Why do you want to traverse a tuple instead of fmap? i.e. what can you do with Foldable/Traversable for (,) that you can't do with Functor? > > My background, as you can probably guess, is beginner. > > > From: Haskell-Cafe on behalf of Chris Smith > Sent: 03 May 2017 08:51 > To: Tony Morris > Cc: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Foldable for (,) > > > > > Replying to myself, I suppose one good answer is that whether or not you care about Foldable instances for tuples, you might care about Traversable instances, and those require Foldable as a superclass. > > > For example, one possible specialization of `traverse` is: > > > traverse :: (a -> IO b) -> (SideValue, a) -> IO (SideValue, b) > > > Jonathon, I don't know how much background you're coming from, so I'd be happy to explain that in more detail if you need it. > > > On Wed, May 3, 2017 at 1:44 AM, Chris Smith wrote: > > I'm also interested in Jonathon's question, so let me try to bring things back to the question. Everyone agrees that there's only one reasonable way to define this instance if it exists. But the question is: why is it defined at all? > > > That's an easy question to answer for Functor, Applicative, and Monad. But I am having trouble giving a simple or accessible answer for Foldable. Do you know one? > > > > > On Wed, May 3, 2017 at 1:32 AM, Tony Morris wrote: > It's Foldable for ((,) a). > > It is not Foldable for any of these things: > > * (,) > * tuples > * pairs > > In fact, to talk about a Foldable for (,) or "tuples" is itself a kind > error. There is no good English name for the type constructor ((,) a) > which I suspect, along with being unfamiliar with utilising the > practical purpose of types (and types of types) is the root cause of all > the confusion in this discussion. > > Ask yourself what the length of this value is: > > [[1,2,3], [4,5,6]] > > Is it 6? What about this one: > > [(1, 'a'), (undefined, 77)] > > Is it 4? No, obviously not, which we can determine by: > > :kind Foldable :: (* -> *) -> Constraint > :kind [] :: * -> * > > Therefore, there is no possible way that the Foldable instance for [] > can inspect the elements (and determine that they are pairs in this > case). By this method, we conclude that the length of the value is 2. It > cannot be anything else, some assumptions about length itself put aside. > > By this ubiquitous and very practical method of reasoning, the length of > any ((,) a) is not only one, but very obviously so. > > > > On 03/05/17 17:21, Jonathon Delgado wrote: >> I sent the following post to the Beginners list a couple of weeks ago (which failed to furnish an actual concrete example that answered the question). Upon request I'm reposting it to Café: >> >> I've seen many threads, including the one going on now, about why we need to have: >> >> length (2,3) = 1 >> product (2,3) = 3 >> sum (2,3) = 3 >> or (True,False) = False >> >> but the justifications all go over my head. Is there a beginner-friendly explanation for why such seemingly unintuitive operations should be allowed by default? >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From olshanskydr at gmail.com Wed May 3 14:38:06 2017 From: olshanskydr at gmail.com (Dmitry Olshansky) Date: Wed, 3 May 2017 17:38:06 +0300 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: Message-ID: Traversable instances (for "singletons" or not) can be implemented _uniformly_ using Functor and Foldable instances. And they are implemented in such way when you derive Traversable. So we need Foldable constraint for the class. E.g. {-# LANGUAGE DeriveFunctor, DeriveFoldable,DeriveTraversable #-} > data D a = D { f1 :: [a], f2 :: (String, a) } deriving (Show, Eq, Functor, Foldable, Traversable) > sum $ D [1..3] ("test",4) 10 > mapM_ print $ sequenceA $ D [[1,2],[3,4]] ("test",[5,6]) D {f1 = [1,3], f2 = ("test",5)} D {f1 = [1,3], f2 = ("test",6)} D {f1 = [1,4], f2 = ("test",5)} D {f1 = [1,4], f2 = ("test",6)} D {f1 = [2,3], f2 = ("test",5)} D {f1 = [2,3], f2 = ("test",6)} D {f1 = [2,4], f2 = ("test",5)} D {f1 = [2,4], f2 = ("test",6)} 2017-05-03 14:34 GMT+03:00 Jonathon Delgado : > Interesting, that's not the one linked to from Dmitry's code. > > In any case, is this correct? > > 1) Traversable is useful for all containers, including ones which can only > hold a single value, such as (,) a. > 2) The traversable definition for containers which can hold multiple > versions requires Foldable. > 3) So Traversable has to depend on Foldable. > 4) So singleton containers also have to implement Foldable, even when it > doesn't really make sense to do so. > > Is there some kind of refactoring which would "fix" this, other than two > unrelated Traversable classes? I understand that it might be impractical to > refactor a widely-used standard library, but I would be interested in how > such a situation could be avoided when starting from scratch. > > > > From: Haskell-Cafe on behalf of Tony > Morris > Sent: 03 May 2017 11:21 > To: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Foldable for (,) > > https://i.imgur.com/A2enuhq.png > > > On 03/05/17 21:17, Jonathon Delgado wrote: > > List.foldr has signature (a -> b -> b) -> b -> [a] -> b, i.e. an actual > list? How is this effected by the Foldable constraint? > > > > > > > > From: Dmitry Olshansky > > Sent: 03 May 2017 10:47 > > To: Jonathon Delgado > > Cc: haskell-cafe at haskell.org > > Subject: Re: [Haskell-cafe] Foldable for (,) > > > > > > > > Look how instance for List is defined. > > > > instance Traversable [] where {-# INLINE traverse #-} -- so that > traverse can fuse traverse f = List.foldr cons_f (pure []) where > cons_f x ys = (:) <$> f x <*> ys It uses List.foldr. Many other instances > do the same. > > Functions in all instances of class should have the same signatures. So > we have to add Foldable constraint to the class. > > Of cause we can implement 'foldr' internaly in 'traverse' if needed (as > well as fmap). > > But this is not so good and more important that in this case we don't > know how to derive Traversable instances automatically. > > > > So the answer - many instances wouldn't compile and DeriveTraversable > wouldn't work. > > > > > > > > 2017-05-03 12:56 GMT+03:00 Jonathon Delgado : > > OK, I understand why Traversable is useful here - thank you Chris and > Dmitry! > > > > The next question is why Traversable requires Foldable. I looked at the > source, and couldn't see where Foldable is being used, other than as a > constraint on Traversable. To put the question differently, what would fail > to compile if this constraint was removed? > > > > > > > > From: Dmitry Olshansky > > Sent: 03 May 2017 09:53 > > To: Jonathon Delgado > > > > > > Cc: haskell-cafe at haskell.org > > Subject: Re: [Haskell-cafe] Foldable for (,) > > > > > > > > > > > > With fmap you can only change all values in some "container". > > > > With Foldable you can "fold" it, i.e. calculate some "scalar" result. > > > > With Traversable you can "change order of two containers": > >> sequenceA [[1,2,3],[4,5]] > > [[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]] > >> sequenceA ("test",[2,3,4]) > > [("test",2),("test",3),("test",4)] > >> sequenceA ("test",([1,2,3],[4,5,6])) > > ([1,2,3],("test",[4,5,6])) > > > > > > > > > > > > 2017-05-03 12:12 GMT+03:00 Jonathon Delgado : > > Why do you want to traverse a tuple instead of fmap? i.e. what can you > do with Foldable/Traversable for (,) that you can't do with Functor? > > > > My background, as you can probably guess, is beginner. > > > > > > From: Haskell-Cafe on behalf of > Chris Smith > > Sent: 03 May 2017 08:51 > > To: Tony Morris > > Cc: haskell-cafe at haskell.org > > Subject: Re: [Haskell-cafe] Foldable for (,) > > > > > > > > > > Replying to myself, I suppose one good answer is that whether or not you > care about Foldable instances for tuples, you might care about Traversable > instances, and those require Foldable as a superclass. > > > > > > For example, one possible specialization of `traverse` is: > > > > > > traverse :: (a -> IO b) -> (SideValue, a) -> IO (SideValue, b) > > > > > > Jonathon, I don't know how much background you're coming from, so I'd be > happy to explain that in more detail if you need it. > > > > > > On Wed, May 3, 2017 at 1:44 AM, Chris Smith wrote: > > > > I'm also interested in Jonathon's question, so let me try to bring > things back to the question. Everyone agrees that there's only one > reasonable way to define this instance if it exists. But the question is: > why is it defined at all? > > > > > > That's an easy question to answer for Functor, Applicative, and Monad. > But I am having trouble giving a simple or accessible answer for Foldable. > Do you know one? > > > > > > > > > > On Wed, May 3, 2017 at 1:32 AM, Tony Morris > wrote: > > It's Foldable for ((,) a). > > > > It is not Foldable for any of these things: > > > > * (,) > > * tuples > > * pairs > > > > In fact, to talk about a Foldable for (,) or "tuples" is itself a kind > > error. There is no good English name for the type constructor ((,) a) > > which I suspect, along with being unfamiliar with utilising the > > practical purpose of types (and types of types) is the root cause of all > > the confusion in this discussion. > > > > Ask yourself what the length of this value is: > > > > [[1,2,3], [4,5,6]] > > > > Is it 6? What about this one: > > > > [(1, 'a'), (undefined, 77)] > > > > Is it 4? No, obviously not, which we can determine by: > > > > :kind Foldable :: (* -> *) -> Constraint > > :kind [] :: * -> * > > > > Therefore, there is no possible way that the Foldable instance for [] > > can inspect the elements (and determine that they are pairs in this > > case). By this method, we conclude that the length of the value is 2. It > > cannot be anything else, some assumptions about length itself put aside. > > > > By this ubiquitous and very practical method of reasoning, the length of > > any ((,) a) is not only one, but very obviously so. > > > > > > > > On 03/05/17 17:21, Jonathon Delgado wrote: > >> I sent the following post to the Beginners list a couple of weeks ago > (which failed to furnish an actual concrete example that answered the > question). Upon request I'm reposting it to Café: > >> > >> I've seen many threads, including the one going on now, about why we > need to have: > >> > >> length (2,3) = 1 > >> product (2,3) = 3 > >> sum (2,3) = 3 > >> or (True,False) = False > >> > >> but the justifications all go over my head. Is there a > beginner-friendly explanation for why such seemingly unintuitive operations > should be allowed by default? > >> _______________________________________________ > >> Haskell-Cafe mailing list > >> To (un)subscribe, modify options or view archives go to: > >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > > Haskell-Cafe Info Page > mail.haskell.org > This mailing list is for the discussion of topics related to Haskell. The > volume may at times be high, as the scope is broader than the main Haskell > mailing list. > > >> Only members subscribed via the mailman list are allowed to post. > > > > > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > > Haskell-Cafe Info Page > mail.haskell.org > This mailing list is for the discussion of topics related to Haskell. The > volume may at times be high, as the scope is broader than the main Haskell > mailing list. > > > Only members subscribed via the mailman list are allowed to post. > > > > > > > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > > > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > > > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > > > https://i.imgur.com/A2enuhq.png > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rae at cs.brynmawr.edu Wed May 3 14:43:48 2017 From: rae at cs.brynmawr.edu (Richard Eisenberg) Date: Wed, 3 May 2017 10:43:48 -0400 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: Message-ID: <493A55BD-E98A-43A1-A7A5-818B45A6BE66@cs.brynmawr.edu> To me, the fact that DeriveTraversable requires a Foldable instance is not an argument saying that Foldable needs to be a superclass of Traversable. It just restricts the usefulness of DeriveTraversable. We could always advertise that DeriveTraversable works only on types with Foldable instances -- no need to bake this restriction into the superclass constraints of Traversable. To be clear, I'm *not* arguing that Foldable shouldn't be a superclass of Traversable. I'm not knowledgeable enough on the specifics to make that claim. I *am* arguing that support for DeriveTraversable doesn't seem to a great argument for putting Foldable as a superclass of Traversable, though. Richard > On May 3, 2017, at 10:38 AM, Dmitry Olshansky wrote: > > Traversable instances (for "singletons" or not) can be implemented _uniformly_ using Functor and Foldable instances. > And they are implemented in such way when you derive Traversable. So we need Foldable constraint for the class. > > E.g. > {-# LANGUAGE DeriveFunctor, DeriveFoldable,DeriveTraversable #-} > > data D a = D { f1 :: [a], f2 :: (String, a) } deriving (Show, Eq, Functor, Foldable, Traversable) > > sum $ D [1..3] ("test",4) > 10 > > mapM_ print $ sequenceA $ D [[1,2],[3,4]] ("test",[5,6]) > D {f1 = [1,3], f2 = ("test",5)} > D {f1 = [1,3], f2 = ("test",6)} > D {f1 = [1,4], f2 = ("test",5)} > D {f1 = [1,4], f2 = ("test",6)} > D {f1 = [2,3], f2 = ("test",5)} > D {f1 = [2,3], f2 = ("test",6)} > D {f1 = [2,4], f2 = ("test",5)} > D {f1 = [2,4], f2 = ("test",6)} > > > > 2017-05-03 14:34 GMT+03:00 Jonathon Delgado >: > Interesting, that's not the one linked to from Dmitry's code. > > In any case, is this correct? > > 1) Traversable is useful for all containers, including ones which can only hold a single value, such as (,) a. > 2) The traversable definition for containers which can hold multiple versions requires Foldable. > 3) So Traversable has to depend on Foldable. > 4) So singleton containers also have to implement Foldable, even when it doesn't really make sense to do so. > > Is there some kind of refactoring which would "fix" this, other than two unrelated Traversable classes? I understand that it might be impractical to refactor a widely-used standard library, but I would be interested in how such a situation could be avoided when starting from scratch. > > > > From: Haskell-Cafe > on behalf of Tony Morris > > Sent: 03 May 2017 11:21 > To: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Foldable for (,) > > https://i.imgur.com/A2enuhq.png > > > On 03/05/17 21:17, Jonathon Delgado wrote: > > List.foldr has signature (a -> b -> b) -> b -> [a] -> b, i.e. an actual list? How is this effected by the Foldable constraint? > > > > > > > > From: Dmitry Olshansky > > > Sent: 03 May 2017 10:47 > > To: Jonathon Delgado > > Cc: haskell-cafe at haskell.org > > Subject: Re: [Haskell-cafe] Foldable for (,) > > > > > > > > Look how instance for List is defined. > > > > instance Traversable [] where {-# INLINE traverse #-} -- so that traverse can fuse traverse f = List.foldr cons_f (pure []) where cons_f x ys = (:) <$> f x <*> ys It uses List.foldr. Many other instances do the same. > > Functions in all instances of class should have the same signatures. So we have to add Foldable constraint to the class. > > Of cause we can implement 'foldr' internaly in 'traverse' if needed (as well as fmap). > > But this is not so good and more important that in this case we don't know how to derive Traversable instances automatically. > > > > So the answer - many instances wouldn't compile and DeriveTraversable wouldn't work. > > > > > > > > 2017-05-03 12:56 GMT+03:00 Jonathon Delgado >: > > OK, I understand why Traversable is useful here - thank you Chris and Dmitry! > > > > The next question is why Traversable requires Foldable. I looked at the source, and couldn't see where Foldable is being used, other than as a constraint on Traversable. To put the question differently, what would fail to compile if this constraint was removed? > > > > > > > > From: Dmitry Olshansky > > > Sent: 03 May 2017 09:53 > > To: Jonathon Delgado > > > > > > Cc: haskell-cafe at haskell.org > > Subject: Re: [Haskell-cafe] Foldable for (,) > > > > > > > > > > > > With fmap you can only change all values in some "container". > > > > With Foldable you can "fold" it, i.e. calculate some "scalar" result. > > > > With Traversable you can "change order of two containers": > >> sequenceA [[1,2,3],[4,5]] > > [[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]] > >> sequenceA ("test",[2,3,4]) > > [("test",2),("test",3),("test",4)] > >> sequenceA ("test",([1,2,3],[4,5,6])) > > ([1,2,3],("test",[4,5,6])) > > > > > > > > > > > > 2017-05-03 12:12 GMT+03:00 Jonathon Delgado >: > > Why do you want to traverse a tuple instead of fmap? i.e. what can you do with Foldable/Traversable for (,) that you can't do with Functor? > > > > My background, as you can probably guess, is beginner. > > > > > > From: Haskell-Cafe > on behalf of Chris Smith > > > Sent: 03 May 2017 08:51 > > To: Tony Morris > > Cc: haskell-cafe at haskell.org > > Subject: Re: [Haskell-cafe] Foldable for (,) > > > > > > > > > > Replying to myself, I suppose one good answer is that whether or not you care about Foldable instances for tuples, you might care about Traversable instances, and those require Foldable as a superclass. > > > > > > For example, one possible specialization of `traverse` is: > > > > > > traverse :: (a -> IO b) -> (SideValue, a) -> IO (SideValue, b) > > > > > > Jonathon, I don't know how much background you're coming from, so I'd be happy to explain that in more detail if you need it. > > > > > > On Wed, May 3, 2017 at 1:44 AM, Chris Smith > wrote: > > > > I'm also interested in Jonathon's question, so let me try to bring things back to the question. Everyone agrees that there's only one reasonable way to define this instance if it exists. But the question is: why is it defined at all? > > > > > > That's an easy question to answer for Functor, Applicative, and Monad. But I am having trouble giving a simple or accessible answer for Foldable. Do you know one? > > > > > > > > > > On Wed, May 3, 2017 at 1:32 AM, Tony Morris > wrote: > > It's Foldable for ((,) a). > > > > It is not Foldable for any of these things: > > > > * (,) > > * tuples > > * pairs > > > > In fact, to talk about a Foldable for (,) or "tuples" is itself a kind > > error. There is no good English name for the type constructor ((,) a) > > which I suspect, along with being unfamiliar with utilising the > > practical purpose of types (and types of types) is the root cause of all > > the confusion in this discussion. > > > > Ask yourself what the length of this value is: > > > > [[1,2,3], [4,5,6]] > > > > Is it 6? What about this one: > > > > [(1, 'a'), (undefined, 77)] > > > > Is it 4? No, obviously not, which we can determine by: > > > > :kind Foldable :: (* -> *) -> Constraint > > :kind [] :: * -> * > > > > Therefore, there is no possible way that the Foldable instance for [] > > can inspect the elements (and determine that they are pairs in this > > case). By this method, we conclude that the length of the value is 2. It > > cannot be anything else, some assumptions about length itself put aside. > > > > By this ubiquitous and very practical method of reasoning, the length of > > any ((,) a) is not only one, but very obviously so. > > > > > > > > On 03/05/17 17:21, Jonathon Delgado wrote: > >> I sent the following post to the Beginners list a couple of weeks ago (which failed to furnish an actual concrete example that answered the question). Upon request I'm reposting it to Café: > >> > >> I've seen many threads, including the one going on now, about why we need to have: > >> > >> length (2,3) = 1 > >> product (2,3) = 3 > >> sum (2,3) = 3 > >> or (True,False) = False > >> > >> but the justifications all go over my head. Is there a beginner-friendly explanation for why such seemingly unintuitive operations should be allowed by default? > >> _______________________________________________ > >> Haskell-Cafe mailing list > >> To (un)subscribe, modify options or view archives go to: > >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > > Haskell-Cafe Info Page > mail.haskell.org > This mailing list is for the discussion of topics related to Haskell. The volume may at times be high, as the scope is broader than the main Haskell mailing list. > > >> Only members subscribed via the mailman list are allowed to post. > > > > > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > > Haskell-Cafe Info Page > mail.haskell.org > This mailing list is for the discussion of topics related to Haskell. The volume may at times be high, as the scope is broader than the main Haskell mailing list. > > > Only members subscribed via the mailman list are allowed to post. > > > > > > > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > > > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > > > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > > > https://i.imgur.com/A2enuhq.png > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From michael at orlitzky.com Wed May 3 15:34:07 2017 From: michael at orlitzky.com (Michael Orlitzky) Date: Wed, 3 May 2017 11:34:07 -0400 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: Message-ID: <0e5fad97-1b16-4fa6-6e46-9cc6f6174587@orlitzky.com> On 05/03/2017 04:44 AM, Chris Smith wrote: > I'm also interested in Jonathon's question, so let me try to bring > things back to the question. Everyone agrees that there's only one > reasonable way to define this instance if it exists. But the question > is: why is it defined at all? > `const 42` is an equally-reasonable implementation to me. If the output is nonsense, who cares what particular nonsense it is? These are all objectively stupid results: length (2,3) = 1 product (2,3) = 3 sum (2,3) = 3 or (True,False) = False Of course you can make up some reasoning that will result in that behavior. For example, * the type ((,) a) must be Traversable * all Traversables should be Foldables * the "length" function should work on Foldables * `const 1` is a fine implementation of length .. etc. (Those are by no means the only assumptions that would lead to the same results.) But normally, when you have a set of assumptions that result in garbage, you don't just shrug and try to convince yourself that maybe the conclusions aren't so bad after all. The point of the type system is not to put stupid behavior on solid theoretical grounds; it's to reject incorrect programs, and "length (2,3)" is an incorrect program. By analogy, ask the same question about, say, PHP. Question: why is "foo" == TRUE in PHP? Answer: it makes perfect sense, once you understand blah blah herp derp. No, it's stupid, and your reasoning is stupid if you can justify it. From gershomb at gmail.com Wed May 3 16:21:07 2017 From: gershomb at gmail.com (Gershom B) Date: Wed, 3 May 2017 12:21:07 -0400 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: <0e5fad97-1b16-4fa6-6e46-9cc6f6174587@orlitzky.com> References: <0e5fad97-1b16-4fa6-6e46-9cc6f6174587@orlitzky.com> Message-ID: On May 3, 2017 at 11:36:00 AM, Michael Orlitzky (michael at orlitzky.com) wrote: > On 05/03/2017 04:44 AM, Chris Smith wrote: > > I'm also interested in Jonathon's question, so let me try to bring > > things back to the question. Everyone agrees that there's only one > > reasonable way to define this instance if it exists. But the question > > is: why is it defined at all? > > > > `const 42` is an equally-reasonable implementation to me. If the output > is nonsense, who cares what particular nonsense it is? > > These are all objectively stupid results: > > By analogy, ask the same question about, say, PHP. > > Question: why is "foo" == TRUE in PHP? > Answer: it makes perfect sense, once you understand blah blah herp derp. > > No, it's stupid, and your reasoning is stupid if you can justify it. We’ve had some discussions about civility lately. This is also about having a productive discussion as well, I think. Comments like the above don’t meaningfully contribute to the discussion, and while they call “results” “objectively stupid” and not people, they tend to raise the temperature of a discussion in such a way that the latter seems only a few more flamewar posts away. I know people have deeply held opinions on things, but simply calling things “objectively stupid” repeatedly and loudly isn’t going to change any of those opinions. We know it won’t do that, because it hasn’t done that for the last two (?) years already. What we know it does, after experiencing it for the past two-ish years, is just make everyone sick of the mailinglists and increasingly testy towards one another, which is an outcome I think nobody wants. Can we stop with this, please? —Gershom From blaze at ruddy.ru Wed May 3 17:11:44 2017 From: blaze at ruddy.ru (Andrey Sverdlichenko) Date: Wed, 03 May 2017 17:11:44 +0000 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: <0e5fad97-1b16-4fa6-6e46-9cc6f6174587@orlitzky.com> References: <0e5fad97-1b16-4fa6-6e46-9cc6f6174587@orlitzky.com> Message-ID: This is probably twentieth time this question arises. Discussion quickly boils down to people liking convenient syntax sugar Foldable instance gives (traverse pair, etc), versus people who don't like absurd semantic which becomes correct with such instances. Personally, I'm in the second camp, but Foldable instance isn't going anywhere. But alternative Prelude is always the option. On Wed, May 3, 2017 at 11:37 AM Michael Orlitzky wrote: > On 05/03/2017 04:44 AM, Chris Smith wrote: > > I'm also interested in Jonathon's question, so let me try to bring > > things back to the question. Everyone agrees that there's only one > > reasonable way to define this instance if it exists. But the question > > is: why is it defined at all? > > > > `const 42` is an equally-reasonable implementation to me. If the output > is nonsense, who cares what particular nonsense it is? > > These are all objectively stupid results: > > length (2,3) = 1 > product (2,3) = 3 > sum (2,3) = 3 > or (True,False) = False > > Of course you can make up some reasoning that will result in that > behavior. For example, > > * the type ((,) a) must be Traversable > * all Traversables should be Foldables > * the "length" function should work on Foldables > * `const 1` is a fine implementation of length > .. etc. > > (Those are by no means the only assumptions that would lead to the same > results.) > > But normally, when you have a set of assumptions that result in garbage, > you don't just shrug and try to convince yourself that maybe the > conclusions aren't so bad after all. The point of the type system is not > to put stupid behavior on solid theoretical grounds; it's to reject > incorrect programs, and "length (2,3)" is an incorrect program. > > By analogy, ask the same question about, say, PHP. > > Question: why is "foo" == TRUE in PHP? > Answer: it makes perfect sense, once you understand blah blah herp derp. > > No, it's stupid, and your reasoning is stupid if you can justify it. > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From allbery.b at gmail.com Wed May 3 17:37:49 2017 From: allbery.b at gmail.com (Brandon Allbery) Date: Wed, 3 May 2017 13:37:49 -0400 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: <0e5fad97-1b16-4fa6-6e46-9cc6f6174587@orlitzky.com> Message-ID: On Wed, May 3, 2017 at 1:11 PM, Andrey Sverdlichenko wrote: > people who don't like absurd semantic Absurd like topology? Like category theory? Heck, like negative numbers? -- brandon s allbery kf8nh sine nomine associates allbery.b at gmail.com ballbery at sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net -------------- next part -------------- An HTML attachment was scrubbed... URL: From blaze at ruddy.ru Wed May 3 17:56:25 2017 From: blaze at ruddy.ru (Andrey Sverdlichenko) Date: Wed, 03 May 2017 17:56:25 +0000 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: <0e5fad97-1b16-4fa6-6e46-9cc6f6174587@orlitzky.com> Message-ID: Like the length of the entity which does not have a length. I absolutely won't mind having this function under the name of foldDepth or numberOfElements or maybe size, whatever, but the length is a linear dimension, and even tree does not have it, leaving alone tuple. Naming in software engineering is a hard problem, and here we failed miserably. On Wed, May 3, 2017 at 1:37 PM Brandon Allbery wrote: > > On Wed, May 3, 2017 at 1:11 PM, Andrey Sverdlichenko > wrote: > >> people who don't like absurd semantic > > > Absurd like topology? Like category theory? Heck, like negative numbers? > > > -- > brandon s allbery kf8nh sine nomine > associates > allbery.b at gmail.com > ballbery at sinenomine.net > unix, openafs, kerberos, infrastructure, xmonad > http://sinenomine.net > -------------- next part -------------- An HTML attachment was scrubbed... URL: From cdsmith at gmail.com Wed May 3 18:01:04 2017 From: cdsmith at gmail.com (Chris Smith) Date: Wed, 3 May 2017 11:01:04 -0700 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: <66f63099-59ba-3aac-74fb-5d0f83ebf1e5@gmail.com> References: <66f63099-59ba-3aac-74fb-5d0f83ebf1e5@gmail.com> Message-ID: It's also interesting, though, to distinguish between two questions. You are asking whether the Foldable superclass *costs* anything. Others are asking whether it *adds* anything. It seems likely, as you say, that the Foldable superclass doesn't cost us any possible Traversable instances. You can probably demonstrate this by implementing foldMap in terms of traverse and some Applicative that lets you accumulate state. (ST? That would definitely work, but feels like driving in a nail with a sledgehammer.) But the superclass does force Foldable on tuples, which has cost quite a bit in the long run! So what is on the benefits side of the balance? I'm very interested in this. Possible answers that I see are. If a substantial number of uses of Traversable also require Foldable, then it makes them more concise. But I am not at all sure that's the case. One interesting case here is mapM versus mapM_. The former requires Traversable, but the latter is implementable from just Foldable. It would be a shame if you could use mapM with some types, but not mapM_. On Wed, May 3, 2017 at 4:56 AM, MarLinn wrote: > It's a nice challenge to come up with datatypes that could be Traversable > but not Foldable. > > First of all, you can think of Traversable as an extension of Functor. > Instead of only mapping over the structure with a pure function, you can > now also map over it with a "functorial function" (a -> f b) (I don't know > of a better name, so I'm inventing one.) What that means is to have a > Traversable structure, you need to have the ability to touch every element. > If you can touch every element, why would you not be able to feed them all > into a folding function? > > Only a few possible anwers come to mind for me: > > > 1. There might be no obvious ordering. But in practice, you just > invent one. > 2. The structure might be infinite, so folding would never succeed. > But laziness ftw. > 3. Generalizing the previous answer, the structure might be computed > ad-hoc and contain fixed points. That alone might not suffice, but it > sounds like a more interesting starting point. > 4. Generalizing a bit differently, the structure might be computed > ad-hoc… because it's IO. IO surely can't be Foldable. But could it be > Traversable? Well… no actually, because order is important. > > So can you come up with a structure that is computed ad-hoc, that contains > fixed points, and where ordering is unimportant? Good luck. > > Cheers. > > > > On 2017-05-03 11:56, Jonathon Delgado wrote: > > OK, I understand why Traversable is useful here - thank you Chris and Dmitry! > > The next question is why Traversable requires Foldable. I looked at the source, and couldn't see where Foldable is being used, other than as a constraint on Traversable. To put the question differently, what would fail to compile if this constraint was removed? > > > > From: Dmitry Olshansky > Sent: 03 May 2017 09:53 > To: Jonathon Delgado > Cc: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Foldable for (,) > > > > > > With fmap you can only change all values in some "container". > > With Foldable you can "fold" it, i.e. calculate some "scalar" result. > > With Traversable you can "change order of two containers": > > sequenceA [[1,2,3],[4,5]] > > [[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]] > > sequenceA ("test",[2,3,4]) > > [("test",2),("test",3),("test",4)] > > sequenceA ("test",([1,2,3],[4,5,6])) > > ([1,2,3],("test",[4,5,6])) > > > > > > 2017-05-03 12:12 GMT+03:00 Jonathon Delgado : > Why do you want to traverse a tuple instead of fmap? i.e. what can you do with Foldable/Traversable for (,) that you can't do with Functor? > > My background, as you can probably guess, is beginner. > > > From: Haskell-Cafe on behalf of Chris Smith > Sent: 03 May 2017 08:51 > To: Tony Morris > Cc: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Foldable for (,) > > > > > Replying to myself, I suppose one good answer is that whether or not you care about Foldable instances for tuples, you might care about Traversable instances, and those require Foldable as a superclass. > > > For example, one possible specialization of `traverse` is: > > > traverse :: (a -> IO b) -> (SideValue, a) -> IO (SideValue, b) > > > Jonathon, I don't know how much background you're coming from, so I'd be happy to explain that in more detail if you need it. > > > On Wed, May 3, 2017 at 1:44 AM, Chris Smith wrote: > > I'm also interested in Jonathon's question, so let me try to bring things back to the question. Everyone agrees that there's only one reasonable way to define this instance if it exists. But the question is: why is it defined at all? > > > That's an easy question to answer for Functor, Applicative, and Monad. But I am having trouble giving a simple or accessible answer for Foldable. Do you know one? > > > > > On Wed, May 3, 2017 at 1:32 AM, Tony Morris wrote: > It's Foldable for ((,) a). > > It is not Foldable for any of these things: > > * (,) > * tuples > * pairs > > In fact, to talk about a Foldable for (,) or "tuples" is itself a kind > error. There is no good English name for the type constructor ((,) a) > which I suspect, along with being unfamiliar with utilising the > practical purpose of types (and types of types) is the root cause of all > the confusion in this discussion. > > Ask yourself what the length of this value is: > > [[1,2,3], [4,5,6]] > > Is it 6? What about this one: > > [(1, 'a'), (undefined, 77)] > > Is it 4? No, obviously not, which we can determine by: > > :kind Foldable :: (* -> *) -> Constraint > :kind [] :: * -> * > > Therefore, there is no possible way that the Foldable instance for [] > can inspect the elements (and determine that they are pairs in this > case). By this method, we conclude that the length of the value is 2. It > cannot be anything else, some assumptions about length itself put aside. > > By this ubiquitous and very practical method of reasoning, the length of > any ((,) a) is not only one, but very obviously so. > > > > On 03/05/17 17:21, Jonathon Delgado wrote: > > I sent the following post to the Beginners list a couple of weeks ago (which failed to furnish an actual concrete example that answered the question). Upon request I'm reposting it to Café: > > I've seen many threads, including the one going on now, about why we need to have: > > length (2,3) = 1 > product (2,3) = 3 > sum (2,3) = 3 > or (True,False) = False > > but the justifications all go over my head. Is there a beginner-friendly explanation for why such seemingly unintuitive operations should be allowed by default? > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to:http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to:http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to:http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From monkleyon at gmail.com Wed May 3 18:06:41 2017 From: monkleyon at gmail.com (MarLinn) Date: Wed, 3 May 2017 20:06:41 +0200 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: <0e5fad97-1b16-4fa6-6e46-9cc6f6174587@orlitzky.com> References: <0e5fad97-1b16-4fa6-6e46-9cc6f6174587@orlitzky.com> Message-ID: "Square root of negative one" doesn't make a lot of sense if you ignore the context of complex arithmetic. And it appears to make even less sense that this expression should have several different solutions. Yet quaternions are used today to describe the rotation of robots. In other words: Robots – more than meets the i! Robots are cool. Don't hate on robots. Don't be uncool. An analog is true for /Traversable/ and /Foldable/. Part of the missing context here is that you can write generic functions and later plug in things like the 1-tuple (/Identity/) and get cool things. Just look at lenses. What the instances in question really show is that some operations are transparent in relation to type-level products (i.e. tuples). A different place that shows the same are functions like "first" and "second" that you'll find in the context of profunctors, categories, and arrows. There's more than meets the eye here, and part of the reason you don't get to benefit a lot from it is that that's still an active area of research. From my own gut feeling it may well be where part of the future of programming lies. Which, in my eyes, is pretty cool. But then I'm just a random type still in the process of folding Haskell theory through my Identity. Cheers, MarLinn -------------- next part -------------- An HTML attachment was scrubbed... URL: From olshanskydr at gmail.com Wed May 3 18:35:34 2017 From: olshanskydr at gmail.com (Dmitry Olshansky) Date: Wed, 3 May 2017 21:35:34 +0300 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: <493A55BD-E98A-43A1-A7A5-818B45A6BE66@cs.brynmawr.edu> References: <493A55BD-E98A-43A1-A7A5-818B45A6BE66@cs.brynmawr.edu> Message-ID: Hmm, you are right! My objections were invalid. So I don't know an answer... Really, why we have this constraint? The same question is about Functor. 2017-05-03 17:43 GMT+03:00 Richard Eisenberg : > To me, the fact that DeriveTraversable requires a Foldable instance is not > an argument saying that Foldable needs to be a superclass of Traversable. > It just restricts the usefulness of DeriveTraversable. We could always > advertise that DeriveTraversable works only on types with Foldable > instances -- no need to bake this restriction into the superclass > constraints of Traversable. > > To be clear, I'm *not* arguing that Foldable shouldn't be a superclass of > Traversable. I'm not knowledgeable enough on the specifics to make that > claim. I *am* arguing that support for DeriveTraversable doesn't seem to a > great argument for putting Foldable as a superclass of Traversable, though. > > Richard > > On May 3, 2017, at 10:38 AM, Dmitry Olshansky > wrote: > > Traversable instances (for "singletons" or not) can be implemented > _uniformly_ using Functor and Foldable instances. > And they are implemented in such way when you derive Traversable. So we > need Foldable constraint for the class. > > E.g. > {-# LANGUAGE DeriveFunctor, DeriveFoldable,DeriveTraversable #-} > > data D a = D { f1 :: [a], f2 :: (String, a) } deriving (Show, Eq, > Functor, Foldable, Traversable) > > sum $ D [1..3] ("test",4) > 10 > > mapM_ print $ sequenceA $ D [[1,2],[3,4]] ("test",[5,6]) > D {f1 = [1,3], f2 = ("test",5)} > D {f1 = [1,3], f2 = ("test",6)} > D {f1 = [1,4], f2 = ("test",5)} > D {f1 = [1,4], f2 = ("test",6)} > D {f1 = [2,3], f2 = ("test",5)} > D {f1 = [2,3], f2 = ("test",6)} > D {f1 = [2,4], f2 = ("test",5)} > D {f1 = [2,4], f2 = ("test",6)} > > > > 2017-05-03 14:34 GMT+03:00 Jonathon Delgado : > >> Interesting, that's not the one linked to from Dmitry's code. >> >> In any case, is this correct? >> >> 1) Traversable is useful for all containers, including ones which can >> only hold a single value, such as (,) a. >> 2) The traversable definition for containers which can hold multiple >> versions requires Foldable. >> 3) So Traversable has to depend on Foldable. >> 4) So singleton containers also have to implement Foldable, even when it >> doesn't really make sense to do so. >> >> Is there some kind of refactoring which would "fix" this, other than two >> unrelated Traversable classes? I understand that it might be impractical to >> refactor a widely-used standard library, but I would be interested in how >> such a situation could be avoided when starting from scratch. >> >> >> >> From: Haskell-Cafe on behalf of Tony >> Morris >> Sent: 03 May 2017 11:21 >> To: haskell-cafe at haskell.org >> Subject: Re: [Haskell-cafe] Foldable for (,) >> >> https://i.imgur.com/A2enuhq.png >> >> >> On 03/05/17 21:17, Jonathon Delgado wrote: >> > List.foldr has signature (a -> b -> b) -> b -> [a] -> b, i.e. an actual >> list? How is this effected by the Foldable constraint? >> > >> > >> > >> > From: Dmitry Olshansky >> > Sent: 03 May 2017 10:47 >> > To: Jonathon Delgado >> > Cc: haskell-cafe at haskell.org >> > Subject: Re: [Haskell-cafe] Foldable for (,) >> > >> > >> > >> > Look how instance for List is defined. >> > >> > instance Traversable [] where {-# INLINE traverse #-} -- so that >> traverse can fuse traverse f = List.foldr cons_f (pure []) where >> cons_f x ys = (:) <$> f x <*> ys It uses List.foldr. Many other instances >> do the same. >> > Functions in all instances of class should have the same signatures. So >> we have to add Foldable constraint to the class. >> > Of cause we can implement 'foldr' internaly in 'traverse' if needed (as >> well as fmap). >> > But this is not so good and more important that in this case we don't >> know how to derive Traversable instances automatically. >> > >> > So the answer - many instances wouldn't compile and DeriveTraversable >> wouldn't work. >> > >> > >> > >> > 2017-05-03 12:56 GMT+03:00 Jonathon Delgado : >> > OK, I understand why Traversable is useful here - thank you Chris and >> Dmitry! >> > >> > The next question is why Traversable requires Foldable. I looked at the >> source, and couldn't see where Foldable is being used, other than as a >> constraint on Traversable. To put the question differently, what would fail >> to compile if this constraint was removed? >> > >> > >> > >> > From: Dmitry Olshansky >> > Sent: 03 May 2017 09:53 >> > To: Jonathon Delgado >> > >> > >> > Cc: haskell-cafe at haskell.org >> > Subject: Re: [Haskell-cafe] Foldable for (,) >> > >> > >> > >> > >> > >> > With fmap you can only change all values in some "container". >> > >> > With Foldable you can "fold" it, i.e. calculate some "scalar" result. >> > >> > With Traversable you can "change order of two containers": >> >> sequenceA [[1,2,3],[4,5]] >> > [[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]] >> >> sequenceA ("test",[2,3,4]) >> > [("test",2),("test",3),("test",4)] >> >> sequenceA ("test",([1,2,3],[4,5,6])) >> > ([1,2,3],("test",[4,5,6])) >> > >> > >> > >> > >> > >> > 2017-05-03 12:12 GMT+03:00 Jonathon Delgado : >> > Why do you want to traverse a tuple instead of fmap? i.e. what can you >> do with Foldable/Traversable for (,) that you can't do with Functor? >> > >> > My background, as you can probably guess, is beginner. >> > >> > >> > From: Haskell-Cafe on behalf of >> Chris Smith >> > Sent: 03 May 2017 08:51 >> > To: Tony Morris >> > Cc: haskell-cafe at haskell.org >> > Subject: Re: [Haskell-cafe] Foldable for (,) >> > >> > >> > >> > >> > Replying to myself, I suppose one good answer is that whether or not >> you care about Foldable instances for tuples, you might care about >> Traversable instances, and those require Foldable as a superclass. >> > >> > >> > For example, one possible specialization of `traverse` is: >> > >> > >> > traverse :: (a -> IO b) -> (SideValue, a) -> IO (SideValue, b) >> > >> > >> > Jonathon, I don't know how much background you're coming from, so I'd >> be happy to explain that in more detail if you need it. >> > >> > >> > On Wed, May 3, 2017 at 1:44 AM, Chris Smith wrote: >> > >> > I'm also interested in Jonathon's question, so let me try to bring >> things back to the question. Everyone agrees that there's only one >> reasonable way to define this instance if it exists. But the question is: >> why is it defined at all? >> > >> > >> > That's an easy question to answer for Functor, Applicative, and Monad. >> But I am having trouble giving a simple or accessible answer for Foldable. >> Do you know one? >> > >> > >> > >> > >> > On Wed, May 3, 2017 at 1:32 AM, Tony Morris >> wrote: >> > It's Foldable for ((,) a). >> > >> > It is not Foldable for any of these things: >> > >> > * (,) >> > * tuples >> > * pairs >> > >> > In fact, to talk about a Foldable for (,) or "tuples" is itself a kind >> > error. There is no good English name for the type constructor ((,) a) >> > which I suspect, along with being unfamiliar with utilising the >> > practical purpose of types (and types of types) is the root cause of all >> > the confusion in this discussion. >> > >> > Ask yourself what the length of this value is: >> > >> > [[1,2,3], [4,5,6]] >> > >> > Is it 6? What about this one: >> > >> > [(1, 'a'), (undefined, 77)] >> > >> > Is it 4? No, obviously not, which we can determine by: >> > >> > :kind Foldable :: (* -> *) -> Constraint >> > :kind [] :: * -> * >> > >> > Therefore, there is no possible way that the Foldable instance for [] >> > can inspect the elements (and determine that they are pairs in this >> > case). By this method, we conclude that the length of the value is 2. It >> > cannot be anything else, some assumptions about length itself put aside. >> > >> > By this ubiquitous and very practical method of reasoning, the length of >> > any ((,) a) is not only one, but very obviously so. >> > >> > >> > >> > On 03/05/17 17:21, Jonathon Delgado wrote: >> >> I sent the following post to the Beginners list a couple of weeks ago >> (which failed to furnish an actual concrete example that answered the >> question). Upon request I'm reposting it to Café: >> >> >> >> I've seen many threads, including the one going on now, about why we >> need to have: >> >> >> >> length (2,3) = 1 >> >> product (2,3) = 3 >> >> sum (2,3) = 3 >> >> or (True,False) = False >> >> >> >> but the justifications all go over my head. Is there a >> beginner-friendly explanation for why such seemingly unintuitive operations >> should be allowed by default? >> >> _______________________________________________ >> >> Haskell-Cafe mailing list >> >> To (un)subscribe, modify options or view archives go to: >> >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> >> >> Haskell-Cafe Info Page >> mail.haskell.org >> This mailing list is for the discussion of topics related to Haskell. The >> volume may at times be high, as the scope is broader than the main Haskell >> mailing list. >> >> >> Only members subscribed via the mailman list are allowed to post. >> > >> > >> > _______________________________________________ >> > Haskell-Cafe mailing list >> > To (un)subscribe, modify options or view archives go to: >> > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> >> >> Haskell-Cafe Info Page >> mail.haskell.org >> This mailing list is for the discussion of topics related to Haskell. The >> volume may at times be high, as the scope is broader than the main Haskell >> mailing list. >> >> > Only members subscribed via the mailman list are allowed to post. >> > >> > >> > >> > _______________________________________________ >> > Haskell-Cafe mailing list >> > To (un)subscribe, modify options or view archives go to: >> > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> > Only members subscribed via the mailman list are allowed to post. >> > >> > _______________________________________________ >> > Haskell-Cafe mailing list >> > To (un)subscribe, modify options or view archives go to: >> > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> > Only members subscribed via the mailman list are allowed to post. >> > >> > _______________________________________________ >> > Haskell-Cafe mailing list >> > To (un)subscribe, modify options or view archives go to: >> > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> > Only members subscribed via the mailman list are allowed to post. >> >> >> https://i.imgur.com/A2enuhq.png >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. >> > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From chrisdone at gmail.com Wed May 3 18:46:53 2017 From: chrisdone at gmail.com (Christopher Done) Date: Wed, 3 May 2017 19:46:53 +0100 Subject: [Haskell-cafe] Typing Haskell in Haskell experience Message-ID: I’ve been working through Typing Haskell in Haskell in detail ( https://gist.github.com/chrisdone/0075a16b32bfd4f62b7b), and I noticed that if I change e.g. SourcePrelude.hs from the Hackage package ( http://hackage.haskell.org/package/thih) to have a declaration like this: [("printZ", Just (Forall [] ([] :=> (tString))), [([], ap [econst showMfun, econst (("Z" :>: toScheme (TCon (Tycon "Nat" Star))))])])], In other words printChar = show (Z :: Nat) Where Z is neither defined nor an instance of Show, it type checks just fine. If I replace it with e.g. toScheme (TVar(Tyvar "k" Star)) i.e. “some thing of type k“, then it complains that the instance is ambiguous, which is true. So it seems that THIH will accept any type as an instance of any class without complaint as long as all the type variables have been filled in with the correct kind. This came as a surprise to me, as I’m using it in a project. There is apparently code in the type checker that pays attention to the class environment, and you provide instances to it, but it doesn’t seem to care what instances are provided or not. I believe I’ll have to do some extra work to check that the instances actually exist and are full resolved. I can’t tell whether this is a bug or intended behavior. I tried emailing the author of THIH but his email bounced back. Frankly the actual interesting bit of the type checker — the bit where we resolve class instances — is actually the hardest bit for me to read and the bit I’d like more exposition on. I’ve written a tokenizer, parser, renamer and thanks to THIH an inferer, and a stepper in a small dialect of Haskell I’m calling Duet. There’s an example here: http://chrisdone.com/toys/duet-gamma/ You can see the problem illustrated if you type e.g. the following in the top-left: data Nat = Z | S Natmain = show Z The type inferred is: main = ((show :: (Show Nat) => Nat -> String) (Z :: Nat) :: (Show Nat) => String) Which is at least enough information for me to do a lookup and insert an instance dictionary. But I sort of would have expected the type checker to say “no instance”. It does explicitly say that you have to do your own dependency analysis and renamer, but the instance part isn’t clear to me. Oh, and you also have to write your own kind inference for data type declarations. Who knew implementing a Haskell was so involved? So beware future travelers… THIH is awesome, but these are the things I’ve found missing. Ciao! ​ -------------- next part -------------- An HTML attachment was scrubbed... URL: From allbery.b at gmail.com Wed May 3 18:59:05 2017 From: allbery.b at gmail.com (Brandon Allbery) Date: Wed, 3 May 2017 14:59:05 -0400 Subject: [Haskell-cafe] Typing Haskell in Haskell experience In-Reply-To: References: Message-ID: Doesn't this more or less mirror the problem with instance visibility that leads to the orphan instance problem? On Wed, May 3, 2017 at 2:46 PM, Christopher Done wrote: > I’ve been working through Typing Haskell in Haskell in detail ( > https://gist.github.com/chrisdone/0075a16b32bfd4f62b7b), and I noticed > that if I change e.g. SourcePrelude.hs from the Hackage package ( > http://hackage.haskell.org/package/thih) to have a declaration like this: > > [("printZ", > Just (Forall [] > ([] :=> > (tString))), > [([], > ap [econst showMfun, econst (("Z" :>: toScheme (TCon (Tycon "Nat" Star))))])])], > > In other words > > printChar = show (Z :: Nat) > > Where Z is neither defined nor an instance of Show, it type checks just > fine. If I replace it with e.g. toScheme (TVar(Tyvar "k" Star)) i.e. > “some thing of type k“, then it complains that the instance is ambiguous, > which is true. > > So it seems that THIH will accept any type as an instance of any class > without complaint as long as all the type variables have been filled in > with the correct kind. This came as a surprise to me, as I’m using it in a > project. There is apparently code in the type checker that pays attention > to the class environment, and you provide instances to it, but it doesn’t > seem to care what instances are provided or not. > > I believe I’ll have to do some extra work to check that the instances > actually exist and are full resolved. I can’t tell whether this is a bug or > intended behavior. I tried emailing the author of THIH but his email > bounced back. Frankly the actual interesting bit of the type checker — the > bit where we resolve class instances — is actually the hardest bit for me > to read and the bit I’d like more exposition on. > > I’ve written a tokenizer, parser, renamer and thanks to THIH an inferer, > and a stepper in a small dialect of Haskell I’m calling Duet. There’s an > example here: http://chrisdone.com/toys/duet-gamma/ > > You can see the problem illustrated if you type e.g. the following in the > top-left: > > data Nat = Z | S Natmain = show Z > > The type inferred is: > > main = ((show :: (Show Nat) => Nat -> String) (Z :: Nat) :: (Show Nat) => String) > > Which is at least enough information for me to do a lookup and insert an > instance dictionary. But I sort of would have expected the type checker to > say “no instance”. It does explicitly say that you have to do your own > dependency analysis and renamer, but the instance part isn’t clear to me. > Oh, and you also have to write your own kind inference for data type > declarations. Who knew implementing a Haskell was so involved? > > So beware future travelers… THIH is awesome, but these are the things I’ve > found missing. > > Ciao! > ​ > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -- brandon s allbery kf8nh sine nomine associates allbery.b at gmail.com ballbery at sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net -------------- next part -------------- An HTML attachment was scrubbed... URL: From monkleyon at gmail.com Wed May 3 19:12:20 2017 From: monkleyon at gmail.com (MarLinn) Date: Wed, 3 May 2017 21:12:20 +0200 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: <493A55BD-E98A-43A1-A7A5-818B45A6BE66@cs.brynmawr.edu> Message-ID: On 2017-05-03 20:35, Dmitry Olshansky wrote: > So I don't know an answer... Really, why we have this constraint? The > same question is about Functor. Functor is easy: instance Traversable f => Functor f where fmap = (runIdentity .) . traverse . (pure .) From chrisdone at gmail.com Wed May 3 19:18:33 2017 From: chrisdone at gmail.com (Christopher Done) Date: Wed, 3 May 2017 20:18:33 +0100 Subject: [Haskell-cafe] Typing Haskell in Haskell experience In-Reply-To: References: Message-ID: Are you speculating that THIH probably intentionally leaves how to resolve the particular instance for e.g. `Show Bool` as an exercise for the reader, instead only implementing that Bool satisfies the shape expected for the class head? On 3 May 2017 at 19:59, Brandon Allbery wrote: > Doesn't this more or less mirror the problem with instance visibility that > leads to the orphan instance problem? > > On Wed, May 3, 2017 at 2:46 PM, Christopher Done > wrote: > >> I’ve been working through Typing Haskell in Haskell in detail ( >> https://gist.github.com/chrisdone/0075a16b32bfd4f62b7b), and I noticed >> that if I change e.g. SourcePrelude.hs from the Hackage package ( >> http://hackage.haskell.org/package/thih) to have a declaration like this: >> >> [("printZ", >> Just (Forall [] >> ([] :=> >> (tString))), >> [([], >> ap [econst showMfun, econst (("Z" :>: toScheme (TCon (Tycon "Nat" Star))))])])], >> >> In other words >> >> printChar = show (Z :: Nat) >> >> Where Z is neither defined nor an instance of Show, it type checks just >> fine. If I replace it with e.g. toScheme (TVar(Tyvar "k" Star)) i.e. >> “some thing of type k“, then it complains that the instance is >> ambiguous, which is true. >> >> So it seems that THIH will accept any type as an instance of any class >> without complaint as long as all the type variables have been filled in >> with the correct kind. This came as a surprise to me, as I’m using it in a >> project. There is apparently code in the type checker that pays attention >> to the class environment, and you provide instances to it, but it doesn’t >> seem to care what instances are provided or not. >> >> I believe I’ll have to do some extra work to check that the instances >> actually exist and are full resolved. I can’t tell whether this is a bug or >> intended behavior. I tried emailing the author of THIH but his email >> bounced back. Frankly the actual interesting bit of the type checker — the >> bit where we resolve class instances — is actually the hardest bit for me >> to read and the bit I’d like more exposition on. >> >> I’ve written a tokenizer, parser, renamer and thanks to THIH an inferer, >> and a stepper in a small dialect of Haskell I’m calling Duet. There’s an >> example here: http://chrisdone.com/toys/duet-gamma/ >> >> You can see the problem illustrated if you type e.g. the following in the >> top-left: >> >> data Nat = Z | S Natmain = show Z >> >> The type inferred is: >> >> main = ((show :: (Show Nat) => Nat -> String) (Z :: Nat) :: (Show Nat) => String) >> >> Which is at least enough information for me to do a lookup and insert an >> instance dictionary. But I sort of would have expected the type checker to >> say “no instance”. It does explicitly say that you have to do your own >> dependency analysis and renamer, but the instance part isn’t clear to me. >> Oh, and you also have to write your own kind inference for data type >> declarations. Who knew implementing a Haskell was so involved? >> >> So beware future travelers… THIH is awesome, but these are the things >> I’ve found missing. >> >> Ciao! >> ​ >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. >> > > > > -- > brandon s allbery kf8nh sine nomine > associates > allbery.b at gmail.com > ballbery at sinenomine.net > unix, openafs, kerberos, infrastructure, xmonad > http://sinenomine.net > -------------- next part -------------- An HTML attachment was scrubbed... URL: From allbery.b at gmail.com Wed May 3 19:21:42 2017 From: allbery.b at gmail.com (Brandon Allbery) Date: Wed, 3 May 2017 15:21:42 -0400 Subject: [Haskell-cafe] Typing Haskell in Haskell experience In-Reply-To: References: Message-ID: More that one could argue for two different ways to resolve it: in the typechecker as you describe, or at link time (that is, we codegen references to a dictionary and let the linker determine whether said dictionary exists). Each has drawbacks and advantages. On Wed, May 3, 2017 at 3:18 PM, Christopher Done wrote: > Are you speculating that THIH probably intentionally leaves how to resolve > the particular instance for e.g. `Show Bool` as an exercise for the reader, > instead only implementing that Bool satisfies the shape expected for the > class head? > > On 3 May 2017 at 19:59, Brandon Allbery wrote: > >> Doesn't this more or less mirror the problem with instance visibility >> that leads to the orphan instance problem? >> >> On Wed, May 3, 2017 at 2:46 PM, Christopher Done >> wrote: >> >>> I’ve been working through Typing Haskell in Haskell in detail ( >>> https://gist.github.com/chrisdone/0075a16b32bfd4f62b7b), and I noticed >>> that if I change e.g. SourcePrelude.hs from the Hackage package ( >>> http://hackage.haskell.org/package/thih) to have a declaration like >>> this: >>> >>> [("printZ", >>> Just (Forall [] >>> ([] :=> >>> (tString))), >>> [([], >>> ap [econst showMfun, econst (("Z" :>: toScheme (TCon (Tycon "Nat" Star))))])])], >>> >>> In other words >>> >>> printChar = show (Z :: Nat) >>> >>> Where Z is neither defined nor an instance of Show, it type checks just >>> fine. If I replace it with e.g. toScheme (TVar(Tyvar "k" Star)) i.e. >>> “some thing of type k“, then it complains that the instance is >>> ambiguous, which is true. >>> >>> So it seems that THIH will accept any type as an instance of any class >>> without complaint as long as all the type variables have been filled in >>> with the correct kind. This came as a surprise to me, as I’m using it in a >>> project. There is apparently code in the type checker that pays attention >>> to the class environment, and you provide instances to it, but it doesn’t >>> seem to care what instances are provided or not. >>> >>> I believe I’ll have to do some extra work to check that the instances >>> actually exist and are full resolved. I can’t tell whether this is a bug or >>> intended behavior. I tried emailing the author of THIH but his email >>> bounced back. Frankly the actual interesting bit of the type checker — the >>> bit where we resolve class instances — is actually the hardest bit for me >>> to read and the bit I’d like more exposition on. >>> >>> I’ve written a tokenizer, parser, renamer and thanks to THIH an inferer, >>> and a stepper in a small dialect of Haskell I’m calling Duet. There’s an >>> example here: http://chrisdone.com/toys/duet-gamma/ >>> >>> You can see the problem illustrated if you type e.g. the following in >>> the top-left: >>> >>> data Nat = Z | S Natmain = show Z >>> >>> The type inferred is: >>> >>> main = ((show :: (Show Nat) => Nat -> String) (Z :: Nat) :: (Show Nat) => String) >>> >>> Which is at least enough information for me to do a lookup and insert an >>> instance dictionary. But I sort of would have expected the type checker to >>> say “no instance”. It does explicitly say that you have to do your own >>> dependency analysis and renamer, but the instance part isn’t clear to me. >>> Oh, and you also have to write your own kind inference for data type >>> declarations. Who knew implementing a Haskell was so involved? >>> >>> So beware future travelers… THIH is awesome, but these are the things >>> I’ve found missing. >>> >>> Ciao! >>> ​ >>> >>> _______________________________________________ >>> Haskell-Cafe mailing list >>> To (un)subscribe, modify options or view archives go to: >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >>> Only members subscribed via the mailman list are allowed to post. >>> >> >> >> >> -- >> brandon s allbery kf8nh sine nomine >> associates >> allbery.b at gmail.com >> ballbery at sinenomine.net >> unix, openafs, kerberos, infrastructure, xmonad >> http://sinenomine.net >> > > -- brandon s allbery kf8nh sine nomine associates allbery.b at gmail.com ballbery at sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net -------------- next part -------------- An HTML attachment was scrubbed... URL: From chrisdone at gmail.com Wed May 3 19:28:26 2017 From: chrisdone at gmail.com (Christopher Done) Date: Wed, 3 May 2017 20:28:26 +0100 Subject: [Haskell-cafe] Typing Haskell in Haskell experience In-Reply-To: References: Message-ID: Good points! On 3 May 2017 at 20:21, Brandon Allbery wrote: > More that one could argue for two different ways to resolve it: in the > typechecker as you describe, or at link time (that is, we codegen > references to a dictionary and let the linker determine whether said > dictionary exists). Each has drawbacks and advantages. > > On Wed, May 3, 2017 at 3:18 PM, Christopher Done > wrote: > >> Are you speculating that THIH probably intentionally leaves how to >> resolve the particular instance for e.g. `Show Bool` as an exercise for the >> reader, instead only implementing that Bool satisfies the shape expected >> for the class head? >> >> On 3 May 2017 at 19:59, Brandon Allbery wrote: >> >>> Doesn't this more or less mirror the problem with instance visibility >>> that leads to the orphan instance problem? >>> >>> On Wed, May 3, 2017 at 2:46 PM, Christopher Done >>> wrote: >>> >>>> I’ve been working through Typing Haskell in Haskell in detail ( >>>> https://gist.github.com/chrisdone/0075a16b32bfd4f62b7b), and I noticed >>>> that if I change e.g. SourcePrelude.hs from the Hackage package ( >>>> http://hackage.haskell.org/package/thih) to have a declaration like >>>> this: >>>> >>>> [("printZ", >>>> Just (Forall [] >>>> ([] :=> >>>> (tString))), >>>> [([], >>>> ap [econst showMfun, econst (("Z" :>: toScheme (TCon (Tycon "Nat" Star))))])])], >>>> >>>> In other words >>>> >>>> printChar = show (Z :: Nat) >>>> >>>> Where Z is neither defined nor an instance of Show, it type checks >>>> just fine. If I replace it with e.g. toScheme (TVar(Tyvar "k" Star)) >>>> i.e. “some thing of type k“, then it complains that the instance is >>>> ambiguous, which is true. >>>> >>>> So it seems that THIH will accept any type as an instance of any class >>>> without complaint as long as all the type variables have been filled in >>>> with the correct kind. This came as a surprise to me, as I’m using it in a >>>> project. There is apparently code in the type checker that pays attention >>>> to the class environment, and you provide instances to it, but it doesn’t >>>> seem to care what instances are provided or not. >>>> >>>> I believe I’ll have to do some extra work to check that the instances >>>> actually exist and are full resolved. I can’t tell whether this is a bug or >>>> intended behavior. I tried emailing the author of THIH but his email >>>> bounced back. Frankly the actual interesting bit of the type checker — the >>>> bit where we resolve class instances — is actually the hardest bit for me >>>> to read and the bit I’d like more exposition on. >>>> >>>> I’ve written a tokenizer, parser, renamer and thanks to THIH an >>>> inferer, and a stepper in a small dialect of Haskell I’m calling Duet. >>>> There’s an example here: http://chrisdone.com/toys/duet-gamma/ >>>> >>>> You can see the problem illustrated if you type e.g. the following in >>>> the top-left: >>>> >>>> data Nat = Z | S Natmain = show Z >>>> >>>> The type inferred is: >>>> >>>> main = ((show :: (Show Nat) => Nat -> String) (Z :: Nat) :: (Show Nat) => String) >>>> >>>> Which is at least enough information for me to do a lookup and insert >>>> an instance dictionary. But I sort of would have expected the type checker >>>> to say “no instance”. It does explicitly say that you have to do your own >>>> dependency analysis and renamer, but the instance part isn’t clear to me. >>>> Oh, and you also have to write your own kind inference for data type >>>> declarations. Who knew implementing a Haskell was so involved? >>>> >>>> So beware future travelers… THIH is awesome, but these are the things >>>> I’ve found missing. >>>> >>>> Ciao! >>>> ​ >>>> >>>> _______________________________________________ >>>> Haskell-Cafe mailing list >>>> To (un)subscribe, modify options or view archives go to: >>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >>>> Only members subscribed via the mailman list are allowed to post. >>>> >>> >>> >>> >>> -- >>> brandon s allbery kf8nh sine nomine >>> associates >>> allbery.b at gmail.com >>> ballbery at sinenomine.net >>> unix, openafs, kerberos, infrastructure, xmonad >>> http://sinenomine.net >>> >> >> > > > -- > brandon s allbery kf8nh sine nomine > associates > allbery.b at gmail.com > ballbery at sinenomine.net > unix, openafs, kerberos, infrastructure, xmonad > http://sinenomine.net > -------------- next part -------------- An HTML attachment was scrubbed... URL: From olf at aatal-apotheke.de Wed May 3 21:12:57 2017 From: olf at aatal-apotheke.de (Olaf Klinke) Date: Wed, 3 May 2017 23:12:57 +0200 Subject: [Haskell-cafe] Foldable for (,) Message-ID: <5912F7F6-3D6B-46F7-90CF-5C7E557D3E79@aatal-apotheke.de> Look at the Stream functor in Data.Stream [1]. Below I will argue by examples that while both Foldable and Traversable instances can be defined, the Foldable instance is less likely to produce terminating functions. Streams can be given a Traversable instance easily: instance Traversable Stream where sequenceA (Cons fa fas) = liftA2 Cons fa (sequenceA fas) For some applicatives this will not terminate. For streams of Maybes, sequenceA will either yield Just an infinite stream or return Nothing. Streams of IO actions also seem fine. A possible Foldable instance would suffer the same termination issues due to recursion. But with a monoid, folds over a stream will terminate less often, e.g. instance Foldable Stream where foldMap f (Cons x xs) = mappend (f x) (foldMap f xs) Then, all (xs :: Stream Bool) will diverge for the constant True stream and terminate for all others. -- Olaf [1] http://hackage.haskell.org/package/Stream-0.4.7.2/docs/Data-Stream.html From m.farkasdyck at gmail.com Wed May 3 21:20:14 2017 From: m.farkasdyck at gmail.com (M Farkas-Dyck) Date: Wed, 3 May 2017 16:20:14 -0500 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: <5912F7F6-3D6B-46F7-90CF-5C7E557D3E79@aatal-apotheke.de> References: <5912F7F6-3D6B-46F7-90CF-5C7E557D3E79@aatal-apotheke.de> Message-ID: On 03/05/2017, Olaf Klinke wrote: > Streams can be given a Traversable instance easily: > > instance Traversable Stream where > sequenceA (Cons fa fas) = liftA2 Cons fa (sequenceA fas) > > For some applicatives this will not terminate. For streams of Maybes, > sequenceA will either yield Just an infinite stream or return Nothing. I believe this will never return `Just` an infinite stream — rather, it will not terminate. From spam at scientician.net Wed May 3 22:23:25 2017 From: spam at scientician.net (Bardur Arantsson) Date: Thu, 4 May 2017 00:23:25 +0200 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: <0e5fad97-1b16-4fa6-6e46-9cc6f6174587@orlitzky.com> Message-ID: On 2017-05-03 19:11, Andrey Sverdlichenko wrote: > This is probably twentieth time this question arises. Discussion quickly > boils down to people liking convenient syntax sugar Foldable instance > gives (traverse pair, etc), versus people who don't like absurd semantic > which becomes correct with such instances. Language like "absurd semantic" perpetuates the negativity/confrontation that Gershom was talking about. Please try to avoid such language. (It's absolutely fine to disagree, but phrasing matters.) Regards, From ok at cs.otago.ac.nz Wed May 3 22:58:30 2017 From: ok at cs.otago.ac.nz (Richard A. O'Keefe) Date: Thu, 4 May 2017 10:58:30 +1200 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: <66f63099-59ba-3aac-74fb-5d0f83ebf1e5@gmail.com> Message-ID: What we have here is a feature interaction problem. There's a combination of features (Foldable, Traversable, ((,) a), &c) each of which is sensible and useful, but which together give people a nasty surprise. We also have the combination of a language which is getting a lot of attention in terms of expressiveness, mathematical power, consistency and all manner of goodness BUT less attention with respect to beginners and bears of very little brain like me. If I write something that evaluates to length (2,3), it will quite definitely be unintentional. I'm reminded of a feature that Emacs used to have (and maybe still does): there were lots of commands that beginners were much more likely to type by accident than on purpose, so when you typed on, it would tell you something like "you just typed Ctrl-Meta-Explode, which does XYZ, are you sure you meant to do that?" and if you said yes, it remembered that and would let you use it again. That's one way to try to combine power for experts with safety for beginners. Again, if I remember correctly, PLT Scheme (now Racket) had similar support for beginners, where you could choose different language levels so that beginners didn't have to worry about major or even minor arcana. What I'm wondering here is if there's room in the Haskell world for something similar? Perhaps some sort of Profile: pragma, where profiles can say things like "tuples are not Foldable". Does everyone have "beginner" days, or is it just me? From amindfv at gmail.com Thu May 4 01:09:05 2017 From: amindfv at gmail.com (amindfv at gmail.com) Date: Wed, 3 May 2017 20:09:05 -0500 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: <66f63099-59ba-3aac-74fb-5d0f83ebf1e5@gmail.com> Message-ID: <91FF991B-3AE1-4E7E-8C17-48922094E08E@gmail.com> > El 3 may 2017, a las 17:58, Richard A. O'Keefe escribió: > > What we have here is a feature interaction problem. > There's a combination of features (Foldable, Traversable, ((,) a), &c) > each of which is sensible and useful, but which together give people a > nasty surprise. > > We also have the combination of a language which is getting a lot of > attention in terms of expressiveness, mathematical power, consistency > and all manner of goodness BUT less attention with respect to beginners > and bears of very little brain like me. > > If I write something that evaluates to length (2,3), it will > quite definitely be unintentional. I'm reminded of a feature > that Emacs used to have (and maybe still does): there were lots > of commands that beginners were much more likely to type by > accident than on purpose, so when you typed on, it would tell > you something like "you just typed Ctrl-Meta-Explode, which does > XYZ, are you sure you meant to do that?" and if you said yes, it > remembered that and would let you use it again. That's one way > to try to combine power for experts with safety for beginners. > Again, if I remember correctly, PLT Scheme (now Racket) had > similar support for beginners, where you could choose different > language levels so that beginners didn't have to worry about > major or even minor arcana. > > What I'm wondering here is if there's room in the Haskell world for > something similar? Perhaps some sort of Profile: > pragma, where profiles can say things like "tuples are not Foldable". > > Does everyone have "beginner" days, or is it just me? > > I find that when people write code as teams, on deadlines, they tend to hit every problem - beginner or not - that there's no protection against. Another potentially-interesting angle to look at this from is security: how easy is it to write innocent-looking code which does something unexpected? Tom > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From voldermort at hotmail.com Thu May 4 07:47:35 2017 From: voldermort at hotmail.com (Jonathon Delgado) Date: Thu, 4 May 2017 07:47:35 +0000 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: <91FF991B-3AE1-4E7E-8C17-48922094E08E@gmail.com> References: <66f63099-59ba-3aac-74fb-5d0f83ebf1e5@gmail.com> , <91FF991B-3AE1-4E7E-8C17-48922094E08E@gmail.com> Message-ID: It seems that Traversable is doing two things: 1) Changing the shape of a data structure. 2) Folding over the contents of a data structure. Traversable requires Foldable to enable 2, but Traversable is also applied to types such as (,) where only 1 is relevant. If this is correct, follow-up questions would be: 1) For educational purposes, could these concerns be split without substantial drawback? 2) For practical purposes, could this be done without breaking a lot of existing code? From benno.fuenfstueck at gmail.com Thu May 4 08:05:30 2017 From: benno.fuenfstueck at gmail.com (=?UTF-8?B?QmVubm8gRsO8bmZzdMO8Y2s=?=) Date: Thu, 04 May 2017 08:05:30 +0000 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: <66f63099-59ba-3aac-74fb-5d0f83ebf1e5@gmail.com> <91FF991B-3AE1-4E7E-8C17-48922094E08E@gmail.com> Message-ID: The relation between Foldable and Traversable is similar to the one between Applicative and Monad: Traversable does not require Foldable, but every Traversable has a Foldable instance (given by foldMalDefault). That's why there is the superclass constraint. Jonathon Delgado schrieb am Do., 4. Mai 2017, 09:49: > It seems that Traversable is doing two things: > > 1) Changing the shape of a data structure. > 2) Folding over the contents of a data structure. > > Traversable requires Foldable to enable 2, but Traversable is also applied > to types such as (,) where only 1 is relevant. > > If this is correct, follow-up questions would be: > > 1) For educational purposes, could these concerns be split without > substantial drawback? > 2) For practical purposes, could this be done without breaking a lot of > existing code? > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jeffbrown.the at gmail.com Thu May 4 08:10:42 2017 From: jeffbrown.the at gmail.com (Jeffrey Brown) Date: Thu, 4 May 2017 01:10:42 -0700 Subject: [Haskell-cafe] How should I view this file? It looks like literate Haskell but isn't that file type. Message-ID: I am looking at Text.Markdown. The Types.hs file[1] looks like it's got comments that are meant to be viewed as some form other than plain text -- for instance, , msAddHeadingId :: Bool -- ^ If @True@, an @id@ attribute is added to the heading tag with the value equal to -- the text with only valid CSS identifier characters. -- -- > ## Executive Summary -- -- >

Executive Summary

-- -- Default: @False@ -- -- Since 0.1.13 I thought it might be literate Haskell, but the file ends in .hs, not .lhs. How should I view it? Preferably in Emacs? [1] https://github.com/snoyberg/markdown/blob/master/Text/Markdown/Types.hs -- Jeff Brown | Jeffrey Benjamin Brown Website | Facebook | LinkedIn (spammy, so I often miss messages here) | Github -------------- next part -------------- An HTML attachment was scrubbed... URL: From nickolay.kudasov at gmail.com Thu May 4 08:16:29 2017 From: nickolay.kudasov at gmail.com (Nickolay Kudasov) Date: Thu, 04 May 2017 08:16:29 +0000 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: <66f63099-59ba-3aac-74fb-5d0f83ebf1e5@gmail.com> <91FF991B-3AE1-4E7E-8C17-48922094E08E@gmail.com> Message-ID: Hi Jonathon, Traversable instances do not change the shape of a data structure! On the contrary, the whole purpose of traverse is to combine effectful computations, stored in a structure without changing its shape! While Foldable folds over the contents of a data structure (via Monoid), Traversable allows you to fold over the effects attached to the contents of that structure (via Applicative). It turns out that by using Const applicative functor you can use traverse to perform foldMap! Thus every Traversable is trivially a Foldable (see foldMapDefault). Similarly, every Traversable is trivially a Functor if you use Identity applicative functor (see fmapDefault). This is why Traversable has those Functor and Foldable constraints, not because it relies on fmap or foldMap. Kind regards, Nick On Thu, 4 May 2017 at 10:49 Jonathon Delgado wrote: > It seems that Traversable is doing two things: > > 1) Changing the shape of a data structure. > 2) Folding over the contents of a data structure. > > Traversable requires Foldable to enable 2, but Traversable is also applied > to types such as (,) where only 1 is relevant. > > If this is correct, follow-up questions would be: > > 1) For educational purposes, could these concerns be split without > substantial drawback? > 2) For practical purposes, could this be done without breaking a lot of > existing code? > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From timmelzer at gmail.com Thu May 4 08:17:16 2017 From: timmelzer at gmail.com (Norbert Melzer) Date: Thu, 04 May 2017 08:17:16 +0000 Subject: [Haskell-cafe] How should I view this file? It looks like literate Haskell but isn't that file type. In-Reply-To: References: Message-ID: Isn't this haddock markup? Thats the first I'd check... Jeffrey Brown schrieb am Do., 4. Mai 2017 um 10:12 Uhr: > I am looking at Text.Markdown. The Types.hs file[1] looks like it's got > comments that are meant to be viewed as some form other than plain text -- > for instance, > > , msAddHeadingId :: Bool > -- ^ If @True@, an @id@ attribute is added to the heading tag with > the value equal to > -- the text with only valid CSS identifier characters. > -- > -- > ## Executive Summary > -- > -- >

Executive Summary

> -- > -- Default: @False@ > -- > -- Since 0.1.13 > > I thought it might be literate Haskell, but the file ends in .hs, not .lhs. > > How should I view it? Preferably in Emacs? > > [1] > https://github.com/snoyberg/markdown/blob/master/Text/Markdown/Types.hs > > -- > Jeff Brown | Jeffrey Benjamin Brown > Website | Facebook > | LinkedIn > (spammy, so I often > miss messages here) | Github > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ivan.miljenovic at gmail.com Thu May 4 08:21:17 2017 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Thu, 4 May 2017 18:21:17 +1000 Subject: [Haskell-cafe] How should I view this file? It looks like literate Haskell but isn't that file type. In-Reply-To: References: Message-ID: That's Haddock markup (though the ## one is new for me): https://www.haskell.org/haddock/doc/html/ch03s08.html On 4 May 2017 at 18:10, Jeffrey Brown wrote: > I am looking at Text.Markdown. The Types.hs file[1] looks like it's got > comments that are meant to be viewed as some form other than plain text -- > for instance, > > , msAddHeadingId :: Bool > -- ^ If @True@, an @id@ attribute is added to the heading tag with the > value equal to > -- the text with only valid CSS identifier characters. > -- > -- > ## Executive Summary > -- > -- >

Executive Summary

> -- > -- Default: @False@ > -- > -- Since 0.1.13 > > I thought it might be literate Haskell, but the file ends in .hs, not .lhs. > > How should I view it? Preferably in Emacs? > > [1] https://github.com/snoyberg/markdown/blob/master/Text/Markdown/Types.hs > > -- > Jeff Brown | Jeffrey Benjamin Brown > Website | Facebook | LinkedIn(spammy, so I often miss messages here) > | Github > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -- Ivan Lazar Miljenovic Ivan.Miljenovic at gmail.com http://IvanMiljenovic.wordpress.com From jeffbrown.the at gmail.com Thu May 4 08:24:57 2017 From: jeffbrown.the at gmail.com (Jeffrey Brown) Date: Thu, 4 May 2017 01:24:57 -0700 Subject: [Haskell-cafe] How should I view this file? It looks like literate Haskell but isn't that file type. In-Reply-To: References: Message-ID: Thank you both! I should have posted to beginners; forgot that separate list exists. It's been a while ... On Thu, May 4, 2017 at 1:21 AM, Ivan Lazar Miljenovic < ivan.miljenovic at gmail.com> wrote: > That's Haddock markup (though the ## one is new for me): > https://www.haskell.org/haddock/doc/html/ch03s08.html > > On 4 May 2017 at 18:10, Jeffrey Brown wrote: > > I am looking at Text.Markdown. The Types.hs file[1] looks like it's got > > comments that are meant to be viewed as some form other than plain text > -- > > for instance, > > > > , msAddHeadingId :: Bool > > -- ^ If @True@, an @id@ attribute is added to the heading tag > with the > > value equal to > > -- the text with only valid CSS identifier characters. > > -- > > -- > ## Executive Summary > > -- > > -- >

Executive Summary

> > -- > > -- Default: @False@ > > -- > > -- Since 0.1.13 > > > > I thought it might be literate Haskell, but the file ends in .hs, not > .lhs. > > > > How should I view it? Preferably in Emacs? > > > > [1] https://github.com/snoyberg/markdown/blob/master/Text/ > Markdown/Types.hs > > > > -- > > Jeff Brown | Jeffrey Benjamin Brown > > Website | Facebook | LinkedIn(spammy, so I often miss messages > here) > > | Github > > > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > > > > -- > Ivan Lazar Miljenovic > Ivan.Miljenovic at gmail.com > http://IvanMiljenovic.wordpress.com > -- Jeff Brown | Jeffrey Benjamin Brown Website | Facebook | LinkedIn (spammy, so I often miss messages here) | Github -------------- next part -------------- An HTML attachment was scrubbed... URL: From sivanov at colimite.fr Thu May 4 08:35:16 2017 From: sivanov at colimite.fr (Sergiu Ivanov) Date: Thu, 04 May 2017 10:35:16 +0200 Subject: [Haskell-cafe] How should I view this file? It looks like literate Haskell but isn't that file type. In-Reply-To: References: Message-ID: <87lgqdm33v.fsf@colimite.fr> Thus quoth Jeffrey Brown at 08:10 on Thu, May 04 2017: > > I am looking at Text.Markdown. The Types.hs file[1] looks like it's got > comments that are meant to be viewed as some form other than plain text -- These comments look like typical Haddock comments for me. https://www.haskell.org/haddock/ Haddock is a tool for automatic generation of documentation from Haskell source. > How should I view it? Preferably in Emacs? You could probably run Haddock on this file and then browse the result (with eww, for example). Haddock may also generate outputs in different formats, but I don't have additional information on that functionality off the top of my head. -- Sergiu -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 483 bytes Desc: not available URL: From voldermort at hotmail.com Thu May 4 09:30:46 2017 From: voldermort at hotmail.com (Jonathon Delgado) Date: Thu, 4 May 2017 09:30:46 +0000 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: <66f63099-59ba-3aac-74fb-5d0f83ebf1e5@gmail.com> <91FF991B-3AE1-4E7E-8C17-48922094E08E@gmail.com> , Message-ID: Ay, there's the rub. Traversable over (,) can be expressed as a fold over a single element, but that doesn't mean it should be. All you want in this case is the effect. From: Nickolay Kudasov Sent: 04 May 2017 08:16Subject: Re: [Haskell-cafe] Foldable for (,) .... It turns out that by using Const applicative functor you can use traverse to perform foldMap! Thus every Traversable is trivially a Foldable (see foldMapDefault). Similarly, every Traversable is trivially a Functor if you use Identity applicative functor (see fmapDefault). This is why Traversable has those Functor and Foldable constraints, not because it relies on fmap or foldMap. From ketil at malde.org Thu May 4 10:05:08 2017 From: ketil at malde.org (Ketil Malde) Date: Thu, 04 May 2017 12:05:08 +0200 Subject: [Haskell-cafe] [Biohaskell] hash map/associative structure In-Reply-To: <68C8DAA5-42E3-4DAF-9687-94E9F48F5434@gmail.com> References: <87fugq2vcm.fsf@malde.org> <68C8DAA5-42E3-4DAF-9687-94E9F48F5434@gmail.com> Message-ID: <87y3udx7hn.fsf@malde.org> > I know it may be a long shot, but did you consider using columnar data store like Apache Arrow? Arrow might be an option, but is there a Haskell interface? (Googling gives the obvious hits regarding arrows, and Google doesn't seem to care about me adding +apache to the search, it gives me result where "+apache" is overstruck.) > Without knowing more about your application it is a bit difficult to produce more hints. > What is your application? The short story is that I extract a number of 64-bit values from my data, and want to maintain frequency counts for each unique value. So there'll be on the order of 10^9 (plus/minus an order of magnitude) unique values, with counts ranging from one to a few million (and large values being rare). The long explanation is that I'm doing k-mer counts for molecular sequences, breaking DNA sequence data into overlapping words of fixed size (the parameter k), and counting their occurrences. I encode them as Word64, using two bits per nucleotide (the alphabet is A, C, G, and T). This is of course a fairly staple thing to do, and there is no lack of alternative programs that do it - but I'd like mine to work anyway, and it annoys me to have run into this particular bug. Whether it is my own fault, in the Judy FFI, the GHC runtime or libraries, the libjudy code, GHC compilation issues, or a hardware error. -k -- If I haven't seen further, it is by standing in the footprints of giants From johannes.waldmann at htwk-leipzig.de Thu May 4 11:02:35 2017 From: johannes.waldmann at htwk-leipzig.de (Johannes Waldmann) Date: Thu, 4 May 2017 13:02:35 +0200 Subject: [Haskell-cafe] customize ghci error msg Message-ID: Dear Cafe. I have a "stack repl" which loads 841 modules in ghci. I have to do :set prompt "> " because the default prompt shows all modules loaded, and I never see a value or an error message without an enourmous amount of scrolling. But, even with this prompt - when I get some error on ":r", ghci says "... Failed, modules loaded: ..." and again I have to scroll back five miles. How could I change this message? - Thanks, J.W. https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ghci.html#ghci-cmd-:set%20prompt From Andrew.Butterfield at scss.tcd.ie Thu May 4 07:30:14 2017 From: Andrew.Butterfield at scss.tcd.ie (Andrew Butterfield) Date: Thu, 4 May 2017 08:30:14 +0100 Subject: [Haskell-cafe] Haskell type declaration summary Message-ID: <720A2114-2149-4D92-B646-81CD150B630B@scss.tcd.ie> Dear Haskellers, any quick and easy way to extract all the type declarations from a Haskell source file? (for easy reference) Regards, Andrew Butterfield School of Computer Science & Statistics Trinity College Dublin 2, Ireland From lysxia at gmail.com Thu May 4 13:13:18 2017 From: lysxia at gmail.com (Li-yao Xia) Date: Thu, 4 May 2017 09:13:18 -0400 Subject: [Haskell-cafe] How should I view this file? It looks like literate Haskell but isn't that file type. In-Reply-To: <87lgqdm33v.fsf@colimite.fr> References: <87lgqdm33v.fsf@colimite.fr> Message-ID: You can also see the rendered documentation on Hackage or Stackage. http://hackage.haskell.org/package/markdown-0.1.16/docs/Text-Markdown.html#v:msAddHeadingId Li-yao On 05/04/2017 04:35 AM, Sergiu Ivanov wrote: > Thus quoth Jeffrey Brown at 08:10 on Thu, May 04 2017: >> I am looking at Text.Markdown. The Types.hs file[1] looks like it's got >> comments that are meant to be viewed as some form other than plain text -- > These comments look like typical Haddock comments for me. > > https://www.haskell.org/haddock/ > > Haddock is a tool for automatic generation of documentation from Haskell > source. > >> How should I view it? Preferably in Emacs? > You could probably run Haddock on this file and then browse the result > (with eww, for example). > > Haddock may also generate outputs in different formats, but I don't have > additional information on that functionality off the top of my head. > > -- > Sergiu > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From Andrew.Butterfield at scss.tcd.ie Thu May 4 16:09:53 2017 From: Andrew.Butterfield at scss.tcd.ie (Andrew Butterfield) Date: Thu, 4 May 2017 17:09:53 +0100 Subject: [Haskell-cafe] Haskell type declaration summary In-Reply-To: References: <720A2114-2149-4D92-B646-81CD150B630B@scss.tcd.ie> Message-ID: <1E2232A4-7187-47FA-8B2C-7C2C632106CD@scss.tcd.ie> Hi Kevin, yes - I can do that, but it is tedious to issue each command, and I may not remember what all the types are called (I know that :browse will tell me what things exist in the current module with a capital letter) Also I want to be able to do this for a file different to the one currently loaded in GHCi. Something along the lines of (assuming a unix shell): $> showtypes MyBigMonsterHaskellFile.hs data X = A | B type Name = String newtype Y = Z Name .... $> (maybe with a blank line for each one..) Has no-one rustled up something like this - or do I need to look into Haskell parsing...? Cheers, Andrew > On 4 May 2017, at 16:30, Kevin Quick wrote: > > > You can use ghci's browse: > > $ ghci > Prelude> import Data.Maybe > Prelude Data.Maybe> :browse Data.Maybe > ... > Prelude Data.Maybe> :l MyFile.hs > MyFile Data.Maybe> :browse MyFile > ... > > Andrew Butterfield writes: > >> Dear Haskellers, >> any quick and easy way to extract all the type declarations from a Haskell source file? >> (for easy reference) >> >> Regards, >> >> Andrew Butterfield >> School of Computer Science & Statistics >> Trinity College >> Dublin 2, Ireland >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > Andrew Butterfield School of Computer Science & Statistics Trinity College Dublin 2, Ireland From allbery.b at gmail.com Thu May 4 16:22:39 2017 From: allbery.b at gmail.com (Brandon Allbery) Date: Thu, 4 May 2017 12:22:39 -0400 Subject: [Haskell-cafe] Haskell type declaration summary In-Reply-To: <720A2114-2149-4D92-B646-81CD150B630B@scss.tcd.ie> References: <720A2114-2149-4D92-B646-81CD150B630B@scss.tcd.ie> Message-ID: >From source you'd be looking at using haskell-src-exts. Alternately: - echo :browse | ghci foo.hs - compile it, dump the .hi file (ghc --show-iface foo.hi) likely with postprocessing to only show the types On Thu, May 4, 2017 at 3:30 AM, Andrew Butterfield < Andrew.Butterfield at scss.tcd.ie> wrote: > Dear Haskellers, > any quick and easy way to extract all the type declarations from a > Haskell source file? > (for easy reference) > > Regards, > > Andrew Butterfield > School of Computer Science & Statistics > Trinity College > Dublin 2, Ireland > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -- brandon s allbery kf8nh sine nomine associates allbery.b at gmail.com ballbery at sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net -------------- next part -------------- An HTML attachment was scrubbed... URL: From Andrew.Butterfield at scss.tcd.ie Thu May 4 16:34:35 2017 From: Andrew.Butterfield at scss.tcd.ie (Andrew Butterfield) Date: Thu, 4 May 2017 17:34:35 +0100 Subject: [Haskell-cafe] Haskell type declaration summary In-Reply-To: References: <720A2114-2149-4D92-B646-81CD150B630B@scss.tcd.ie> Message-ID: <85CA99E6-B04E-483E-AD9A-727D9EDF7186@scss.tcd.ie> Dear Brandon, thanks for that - the echo :browse solution is ideal because I can easily write a short Haskell program to filter out the type declarations from the output. In fact it becomes easy to extract other kinds of declarations as well. Here the offside rule really is my friend. I'll post a fully worked solution once I build it. Thanks, Andrew > On 4 May 2017, at 17:22, Brandon Allbery wrote: > > From source you'd be looking at using haskell-src-exts. Alternately: > > - echo :browse | ghci foo.hs > > - compile it, dump the .hi file (ghc --show-iface foo.hi) likely with postprocessing to only show the types > > On Thu, May 4, 2017 at 3:30 AM, Andrew Butterfield > wrote: > Dear Haskellers, > any quick and easy way to extract all the type declarations from a Haskell source file? > (for easy reference) > > Regards, > > Andrew Butterfield > School of Computer Science & Statistics > Trinity College > Dublin 2, Ireland > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > > > > -- > brandon s allbery kf8nh sine nomine associates > allbery.b at gmail.com ballbery at sinenomine.net > unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net Andrew Butterfield School of Computer Science & Statistics Trinity College Dublin 2, Ireland -------------- next part -------------- An HTML attachment was scrubbed... URL: From monkleyon at gmail.com Thu May 4 16:44:00 2017 From: monkleyon at gmail.com (MarLinn) Date: Thu, 4 May 2017 18:44:00 +0200 Subject: [Haskell-cafe] Haskell type declaration summary In-Reply-To: References: <720A2114-2149-4D92-B646-81CD150B630B@scss.tcd.ie> Message-ID: > echo :browse | ghci foo.hs And don't forget you can also do (in ghci) :! echo :browse | ghci foo.hs And, while you're at it: :def browseOther \file -> pure $ ":! echo :browse | ghci \"" ++ file ++ "\"" Endless fun. -------------- next part -------------- An HTML attachment was scrubbed... URL: From olf at aatal-apotheke.de Thu May 4 19:20:42 2017 From: olf at aatal-apotheke.de (Olaf Klinke) Date: Thu, 4 May 2017 21:20:42 +0200 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: <5912F7F6-3D6B-46F7-90CF-5C7E557D3E79@aatal-apotheke.de> Message-ID: <4E00A155-29C1-45CB-B450-896086C19B9C@aatal-apotheke.de> > Am 03.05.2017 um 23:20 schrieb M Farkas-Dyck : > > On 03/05/2017, Olaf Klinke wrote: >> Streams can be given a Traversable instance easily: >> >> instance Traversable Stream where >> sequenceA (Cons fa fas) = liftA2 Cons fa (sequenceA fas) >> >> For some applicatives this will not terminate. For streams of Maybes, >> sequenceA will either yield Just an infinite stream or return Nothing. > > I believe this will never return `Just` an infinite stream — rather, > it will not terminate. Of course you are right, I did not test - the program can only be certain of the Just constructor after knowing that no Nothing occurs in the infinite stream. So perhaps the applicatives where sequenceA terminates and the case where foldMap terminates are the same? Anyways, Data.Traversable has foldMapDefault. Thus it seems the original argument that ((,) a) must have a Foldable instance because we want the Traversable instance is valid. For the same reason we made Applicative a superclass of Monad. One might hence wonder whether the brevity and convenience bought by the Traversable instance is worth the confusion brought about by the Foldable instance. There are similar cases in the mathematical world. Most mathematicians are happy to use the Axiom of Choice, knowing that accepting it leads to things like the Banach-Tarski Paradox. Then there are constructivists who deny the existence of non-measurable sets (because you need the Axiom of Choice to prove their existence), and the Banach-Tarski Paradox goes away. By this analogy, the Foldable instance of ((,) a) is the Banach-Tarski paradox which we accept and avoid to obtain other nice things we need. Olaf From amindfv at gmail.com Thu May 4 20:52:18 2017 From: amindfv at gmail.com (amindfv at gmail.com) Date: Thu, 4 May 2017 15:52:18 -0500 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: <4E00A155-29C1-45CB-B450-896086C19B9C@aatal-apotheke.de> References: <5912F7F6-3D6B-46F7-90CF-5C7E557D3E79@aatal-apotheke.de> <4E00A155-29C1-45CB-B450-896086C19B9C@aatal-apotheke.de> Message-ID: <2F5C5838-1399-4DDD-9335-D0F4E02443B2@gmail.com> > El 4 may 2017, a las 14:20, Olaf Klinke escribió: > [...] > Most mathematicians are happy to use the Axiom of Choice, knowing that accepting it leads to things like the Banach-Tarski Paradox. Then there are constructivists who deny the existence of non-measurable sets (because you need the Axiom of Choice to prove their existence), and the Banach-Tarski Paradox goes away. By this analogy, the Foldable instance of ((,) a) is the Banach-Tarski paradox which we accept and avoid to obtain other nice things we need. This to me is the center of the conversation: we're choosing whether we need the instances badly enough that we tolerate some, ahem, bad behavior. Can you provide specific code examples where you (or others) truly needed those instances to get something done? Tom From monkleyon at gmail.com Thu May 4 20:32:12 2017 From: monkleyon at gmail.com (MarLinn) Date: Thu, 4 May 2017 22:32:12 +0200 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: <2F5C5838-1399-4DDD-9335-D0F4E02443B2@gmail.com> References: <5912F7F6-3D6B-46F7-90CF-5C7E557D3E79@aatal-apotheke.de> <4E00A155-29C1-45CB-B450-896086C19B9C@aatal-apotheke.de> <2F5C5838-1399-4DDD-9335-D0F4E02443B2@gmail.com> Message-ID: <0a51be92-19d3-1c9d-6dc5-70d4fbb16e76@gmail.com> > This to me is the center of the conversation: we're choosing whether we need the instances badly enough that we tolerate some, ahem, bad behavior. I dispute that. To me, the center of the disagreement is between two different kinds of consistency: On the one hand, there's the consistency with a view of the world that treats One as a special number different from all other numbers. This view is based on the real world where singularities seem rampant. On the other side is consistency with a math-y view of the world that wants to unify as much as possible so we can reduce the number of models, thus, work. But if you want to treat the cardinality of one specially, do you want to drop Const and Identity, too? Const is closer to tuples than lists are, so why not cut them out as well? But then we had examples in just this conversation where Const and Identity where really useful. What argument is left to remove instances for tuples? If you can get over the 5-second weirdness of Const, why not tuples? At the end I claim there is no bad behavior. I do give you that there is /missing/ behavior because the choice to have only that one instance per tuple size is a bit arbitrary and misleading. And that is hard to change for now. But do you really want to remove those few instances we do have just because we're not ready to include the others yet? MarLinn -------------- next part -------------- An HTML attachment was scrubbed... URL: From cdsmith at gmail.com Thu May 4 20:52:38 2017 From: cdsmith at gmail.com (Chris Smith) Date: Thu, 4 May 2017 13:52:38 -0700 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: <0a51be92-19d3-1c9d-6dc5-70d4fbb16e76@gmail.com> References: <5912F7F6-3D6B-46F7-90CF-5C7E557D3E79@aatal-apotheke.de> <4E00A155-29C1-45CB-B450-896086C19B9C@aatal-apotheke.de> <2F5C5838-1399-4DDD-9335-D0F4E02443B2@gmail.com> <0a51be92-19d3-1c9d-6dc5-70d4fbb16e76@gmail.com> Message-ID: My answer this is: because Foldable instances on tuples make Haskell programming more dangerous. With all instances, there is some risk of accidental unification with broken programs. But in general, we are saved by one of two things: either the types are special-purpose enough that they are unlikely to occur by accident, or unification just propagates the incorrect type and the compiler merely puts the error message is in the wrong place. With length and tuples, though, we're talking about a type that's used casually in many situations; and the accidental unification does not propagate the type at all. Instead, it just generates incorrect code. That's a bit scary! It's unfortunate that discussions of this tend to get muddied by the possibility of length having a different meaning on tuples. Really, IMHO, that's not even related to the problem. The problem is that accidental unification is more risky here than anywhere other commonly used bit of Haskell that I can find. On Thu, May 4, 2017 at 1:32 PM, MarLinn wrote: > > This to me is the center of the conversation: we're choosing whether we need the instances badly enough that we tolerate some, ahem, bad behavior. > > > I dispute that. To me, the center of the disagreement is between two > different kinds of consistency: On the one hand, there's the consistency > with a view of the world that treats One as a special number different from > all other numbers. This view is based on the real world where singularities > seem rampant. On the other side is consistency with a math-y view of the > world that wants to unify as much as possible so we can reduce the number > of models, thus, work. > > But if you want to treat the cardinality of one specially, do you want to > drop Const and Identity, too? Const is closer to tuples than lists are, so > why not cut them out as well? But then we had examples in just this > conversation where Const and Identity where really useful. What argument is > left to remove instances for tuples? If you can get over the 5-second > weirdness of Const, why not tuples? > At the end I claim there is no bad behavior. I do give you that there is > *missing* behavior because the choice to have only that one instance per > tuple size is a bit arbitrary and misleading. And that is hard to change > for now. But do you really want to remove those few instances we do have > just because we're not ready to include the others yet? > > MarLinn > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From parsonsmatt at gmail.com Thu May 4 21:42:11 2017 From: parsonsmatt at gmail.com (Matt) Date: Thu, 4 May 2017 15:42:11 -0600 Subject: [Haskell-cafe] Foldable for (,) In-Reply-To: References: <5912F7F6-3D6B-46F7-90CF-5C7E557D3E79@aatal-apotheke.de> <4E00A155-29C1-45CB-B450-896086C19B9C@aatal-apotheke.de> <2F5C5838-1399-4DDD-9335-D0F4E02443B2@gmail.com> <0a51be92-19d3-1c9d-6dc5-70d4fbb16e76@gmail.com> Message-ID: Another factor: Foldable and Traversable are both closed under composition, meaning that `newtype Compose f g a = Compose (f (g a))` has the following instances: instance (Foldable f, Foldable g) => Foldable (Compose f g) instance (Traversable f, Traversable g) => Traversable (Compose f g) Removing the Foldable instance for `(,) e` would also remove the Foldable and Traversable instance for any composition of functors containing tuples. If you're writing your code in terms of fixed points of type constructors, then this is a problem. Matt Parsons On Thu, May 4, 2017 at 2:52 PM, Chris Smith wrote: > My answer this is: because Foldable instances on tuples make Haskell > programming more dangerous. > > With all instances, there is some risk of accidental unification with > broken programs. But in general, we are saved by one of two things: either > the types are special-purpose enough that they are unlikely to occur by > accident, or unification just propagates the incorrect type and the > compiler merely puts the error message is in the wrong place. > > With length and tuples, though, we're talking about a type that's used > casually in many situations; and the accidental unification does not > propagate the type at all. Instead, it just generates incorrect code. > That's a bit scary! > > It's unfortunate that discussions of this tend to get muddied by the > possibility of length having a different meaning on tuples. Really, IMHO, > that's not even related to the problem. The problem is that accidental > unification is more risky here than anywhere other commonly used bit of > Haskell that I can find. > > On Thu, May 4, 2017 at 1:32 PM, MarLinn wrote: > >> >> This to me is the center of the conversation: we're choosing whether we need the instances badly enough that we tolerate some, ahem, bad behavior. >> >> >> I dispute that. To me, the center of the disagreement is between two >> different kinds of consistency: On the one hand, there's the consistency >> with a view of the world that treats One as a special number different from >> all other numbers. This view is based on the real world where singularities >> seem rampant. On the other side is consistency with a math-y view of the >> world that wants to unify as much as possible so we can reduce the number >> of models, thus, work. >> >> But if you want to treat the cardinality of one specially, do you want to >> drop Const and Identity, too? Const is closer to tuples than lists are, so >> why not cut them out as well? But then we had examples in just this >> conversation where Const and Identity where really useful. What argument is >> left to remove instances for tuples? If you can get over the 5-second >> weirdness of Const, why not tuples? >> At the end I claim there is no bad behavior. I do give you that there is >> *missing* behavior because the choice to have only that one instance per >> tuple size is a bit arbitrary and misleading. And that is hard to change >> for now. But do you really want to remove those few instances we do have >> just because we're not ready to include the others yet? >> >> MarLinn >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. >> > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthew.fernandez at gmail.com Fri May 5 00:56:36 2017 From: matthew.fernandez at gmail.com (Matthew Fernandez) Date: Thu, 4 May 2017 17:56:36 -0700 Subject: [Haskell-cafe] Vim syntax file typo Message-ID: Hello Haskell Cafe, The attached patch fixes what looks to be a typo in a comment in the Haskell Vim syntax file. Pretty trivial, but I'm mailing it to this list as it's listed as the maintainer of the file and I believe that's the Vim policy. Please let me know if there's somewhere more appropriate I should send this or if you'd prefer me to just submit it as a pull request on the Vim Github. Thanks, Matt -------------- next part -------------- A non-text attachment was scrubbed... Name: vim-haskell-typo.patch Type: text/x-patch Size: 914 bytes Desc: not available URL: From wangbj at gmail.com Fri May 5 01:25:48 2017 From: wangbj at gmail.com (Baojun Wang) Date: Fri, 05 May 2017 01:25:48 +0000 Subject: [Haskell-cafe] http-client(-tls) or http-conduit? Message-ID: Hi cafe, It seems both(all) packages are actively maintained, however, they seem to provide a lots of similar functionalities, is there any preferences to use any one of them, and the reason why (Personally I'd prefer the former because of familiarity)? I've read [ https://haskell-lang.org/library/http-client] but it doesn't have recommendation. Thanks baojun -------------- next part -------------- An HTML attachment was scrubbed... URL: From danburton.email at gmail.com Fri May 5 01:54:58 2017 From: danburton.email at gmail.com (Dan Burton) Date: Thu, 4 May 2017 18:54:58 -0700 Subject: [Haskell-cafe] http-client(-tls) or http-conduit? In-Reply-To: References: Message-ID: http-conduit uses http-client and http-client-tls as dependencies. If your use case is satisfied by http-client(-tls), then feel free to stick with that. http-conduit provides the same functionality, as well as additional functionality for streaming requests and responses. -- Dan Burton On Thu, May 4, 2017 at 6:25 PM, Baojun Wang wrote: > Hi cafe, > > It seems both(all) packages are actively maintained, however, they seem to > provide a lots of similar functionalities, is there any preferences to use > any one of them, and the reason why (Personally I'd prefer the former > because of familiarity)? I've read [https://haskell-lang.org/ > library/http-client] but it doesn't have recommendation. > > Thanks > baojun > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From wangbj at gmail.com Fri May 5 02:28:37 2017 From: wangbj at gmail.com (Baojun Wang) Date: Fri, 05 May 2017 02:28:37 +0000 Subject: [Haskell-cafe] http-client(-tls) or http-conduit? In-Reply-To: References: Message-ID: Thanks! http-client and http-client-tls would suffice, no conduit streaming was involved. On Thu, May 4, 2017 at 18:55 Dan Burton wrote: > http-conduit uses http-client and http-client-tls as dependencies. If your > use case is satisfied by http-client(-tls), then feel free to stick with > that. http-conduit provides the same functionality, as well as additional > functionality for streaming requests and responses. > > -- Dan Burton > > On Thu, May 4, 2017 at 6:25 PM, Baojun Wang wrote: > >> Hi cafe, >> >> It seems both(all) packages are actively maintained, however, they seem >> to provide a lots of similar functionalities, is there any preferences to >> use any one of them, and the reason why (Personally I'd prefer the former >> because of familiarity)? I've read [ >> https://haskell-lang.org/library/http-client] but it doesn't have >> recommendation. >> >> Thanks >> baojun >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From monkleyon at gmail.com Fri May 5 03:55:33 2017 From: monkleyon at gmail.com (MarLinn) Date: Fri, 5 May 2017 05:55:33 +0200 Subject: [Haskell-cafe] Hunting for ghci manual input vs. file input differences again Message-ID: <5433e464-3ca4-705e-4241-f8a6a37b1a20@gmail.com> Hi, I've been working on a kind of constrained version of Data.Dynamic: data Dynamic (c :: * -> Constraint) where Dynamic :: (Typeable a, c a) => a -> Dynamic c The idea is that Data.Dynamic gives up all compile time type information. In this variant I can at least keep a bit of the information around that I have. (In fact I can even "lift" a type into a constraint, thereby keeping /all/ information.) Most of my functions are nailed down, including mappings and traversals. But one group of functions eludes me: functions to change only the constraint, while keeping the value. Here is one of my goal types: castDynamic :: ( Typeable a, c a, d a ) => Dynamic c -> Dynamic d I'm pretty sure I'll have to sprinkle in a Proxy a, but so be it. I've thrown all typing tricks at this function that I know of, from unsafeCoerce over case-of instead of pattern matching, to ScopedTypeVariables. But I couldn't convince ghci to accept my code. So I tried something simpler. castDynamic' :: (Typeable a, c a) => Dynamic Show -> Maybe (Dynamic c) Here's where it gets funny: I can implement this function in ghci interactively just fine. >>> :t \(d :: Dynamic Show) -> case d of Dynamic a -> Dynamic <$> cast a \(d :: Dynamic Show) -> case d of Dynamic a -> Dynamic <$> cast a :: (Typeable a, c a) => Dynamic Show -> Maybe (Dynamic c) But when I enter the exact same code in a file and load it, ghci balks at me because a is too ambiguous. Again, I've tried if it's the monomorphism restriction, or if I need to sprinkle in more (scoped) signatures or explicit forall's etc… nothing helped. What is the difference here? Am I missing an extension? Am I doing something I shouldn't and the interactive mode is just doing me a favor? There was a discussion on this list less than a month ago where it was mentioned that ghci handles polymorphic types differently depending on the source of the code. Is there some documentation on these differences? Any help would be appreciated. Cheers, MarLinn -------------- next part -------------- An HTML attachment was scrubbed... URL: From parsonsmatt at gmail.com Fri May 5 04:48:36 2017 From: parsonsmatt at gmail.com (Matt) Date: Thu, 4 May 2017 22:48:36 -0600 Subject: [Haskell-cafe] Hunting for ghci manual input vs. file input differences again In-Reply-To: <5433e464-3ca4-705e-4241-f8a6a37b1a20@gmail.com> References: <5433e464-3ca4-705e-4241-f8a6a37b1a20@gmail.com> Message-ID: The type `a` only appears in the constraints, not the signature, so GHC has no way of figuring out what it's supposed to be. Furthermore, the type `a` in your signature is *not* the type `a` that's in the GADT -- that's a totally distinct type. I don't think you'll be able to unify the those two types. You can use a `Proxy` argument to explicitly signal to GHC what type it should be, or TypeApplications, but I don't think either of those will help with implementing this. You may also find http://haddock.stackage.org/lts-5.1/constraints-0.8/Data-Constraint.html interesting. Matt Parsons On Thu, May 4, 2017 at 9:55 PM, MarLinn wrote: > Hi, > > I've been working on a kind of constrained version of Data.Dynamic: > > data Dynamic (c :: * -> Constraint) where > Dynamic :: (Typeable a, c a) => a -> Dynamic c > > The idea is that Data.Dynamic gives up all compile time type information. > In this variant I can at least keep a bit of the information around that I > have. (In fact I can even "lift" a type into a constraint, thereby keeping > *all* information.) Most of my functions are nailed down, including > mappings and traversals. But one group of functions eludes me: functions to > change only the constraint, while keeping the value. Here is one of my goal > types: > > castDynamic :: ( Typeable a, c a, d a ) => Dynamic c -> Dynamic d > > I'm pretty sure I'll have to sprinkle in a Proxy a, but so be it. I've > thrown all typing tricks at this function that I know of, from unsafeCoerce > over case-of instead of pattern matching, to ScopedTypeVariables. But I > couldn't convince ghci to accept my code. So I tried something simpler. > > castDynamic' :: (Typeable a, c a) => Dynamic Show -> Maybe (Dynamic c) > > Here's where it gets funny: I can implement this function in ghci > interactively just fine. > > >>> :t \(d :: Dynamic Show) -> case d of Dynamic a -> Dynamic <$> cast a > \(d :: Dynamic Show) -> case d of Dynamic a -> Dynamic <$> cast a > :: (Typeable a, c a) => Dynamic Show -> Maybe (Dynamic c) > > But when I enter the exact same code in a file and load it, ghci balks at > me because a is too ambiguous. Again, I've tried if it's the monomorphism > restriction, or if I need to sprinkle in more (scoped) signatures or > explicit forall's etc… nothing helped. > > What is the difference here? Am I missing an extension? Am I doing > something I shouldn't and the interactive mode is just doing me a favor? > There was a discussion on this list less than a month ago where it was > mentioned that ghci handles polymorphic types differently depending on the > source of the code. Is there some documentation on these differences? Any > help would be appreciated. > > Cheers, > MarLinn > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From kane at kane.cx Fri May 5 05:19:47 2017 From: kane at kane.cx (David Kraeutmann) Date: Fri, 5 May 2017 07:19:47 +0200 Subject: [Haskell-cafe] Hunting for ghci manual input vs. file input differences again In-Reply-To: <5433e464-3ca4-705e-4241-f8a6a37b1a20@gmail.com> References: <5433e464-3ca4-705e-4241-f8a6a37b1a20@gmail.com> Message-ID: This is probably what's happening: https://wiki.haskell.org/GHC/TypeSigsAndAmbiguity On 05/05/2017 05:55 AM, MarLinn wrote: > > Hi, > > I've been working on a kind of constrained version of Data.Dynamic: > > data Dynamic (c :: * -> Constraint) where > Dynamic :: (Typeable a, c a) => a -> Dynamic c > > The idea is that Data.Dynamic gives up all compile time type > information. In this variant I can at least keep a bit of the > information around that I have. (In fact I can even "lift" a type into > a constraint, thereby keeping /all/ information.) Most of my functions > are nailed down, including mappings and traversals. But one group of > functions eludes me: functions to change only the constraint, while > keeping the value. Here is one of my goal types: > > castDynamic :: ( Typeable a, c a, d a ) => Dynamic c -> Dynamic d > > I'm pretty sure I'll have to sprinkle in a Proxy a, but so be it. I've > thrown all typing tricks at this function that I know of, from > unsafeCoerce over case-of instead of pattern matching, to > ScopedTypeVariables. But I couldn't convince ghci to accept my code. > So I tried something simpler. > > castDynamic' :: (Typeable a, c a) => Dynamic Show -> Maybe (Dynamic c) > > Here's where it gets funny: I can implement this function in ghci > interactively just fine. > > >>> :t \(d :: Dynamic Show) -> case d of Dynamic a -> Dynamic <$> cast a > \(d :: Dynamic Show) -> case d of Dynamic a -> Dynamic <$> cast a > :: (Typeable a, c a) => Dynamic Show -> Maybe (Dynamic c) > > But when I enter the exact same code in a file and load it, ghci balks > at me because a is too ambiguous. Again, I've tried if it's the > monomorphism restriction, or if I need to sprinkle in more (scoped) > signatures or explicit forall's etc… nothing helped. > > What is the difference here? Am I missing an extension? Am I doing > something I shouldn't and the interactive mode is just doing me a > favor? There was a discussion on this list less than a month ago where > it was mentioned that ghci handles polymorphic types differently > depending on the source of the code. Is there some documentation on > these differences? Any help would be appreciated. > > Cheers, > MarLinn > > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From monkleyon at gmail.com Fri May 5 11:30:34 2017 From: monkleyon at gmail.com (MarLinn) Date: Fri, 5 May 2017 13:30:34 +0200 Subject: [Haskell-cafe] Hunting for ghci manual input vs. file input differences again In-Reply-To: References: <5433e464-3ca4-705e-4241-f8a6a37b1a20@gmail.com> Message-ID: <908e956c-2f53-4fa7-9d90-e879f597f656@gmail.com> > You can use a `Proxy` argument to explicitly signal to GHC what type > it should be, or TypeApplications, but I don't think either of those > will help with implementing this. I guess you're right. It seems my examples where only working because somewhere along the line types where defaulted to () – throwing away any information I did have. I suppose what I would actually need for the elusive cast is something like a (forall a . c a :=> d a). I found some interesting bits in Data.Constraint.Forall to pursue in that direction, but I'm far from understanding how to use them. Anyway, thanks for the help. MarLinn From tanuki at gmail.com Sat May 6 06:12:04 2017 From: tanuki at gmail.com (Theodore Lief Gannon) Date: Fri, 5 May 2017 23:12:04 -0700 Subject: [Haskell-cafe] List instance of Alternative: why (++)? Message-ID: Fiddling around, I found myself wanting: coalesce :: [a] -> [a] -> [a] -- or -- :: (Foldable t) => t a -> t a -> t a coalesce a b = if null a then b else a I expected this to be (<|>) (it is for Maybe!) but instead I find no canonical implementation of it anywhere, and what seems like a useless instance Alternative []. What's the rationale? -------------- next part -------------- An HTML attachment was scrubbed... URL: From cdsmith at gmail.com Sat May 6 06:36:07 2017 From: cdsmith at gmail.com (Chris Smith) Date: Fri, 5 May 2017 23:36:07 -0700 Subject: [Haskell-cafe] List instance of Alternative: why (++)? In-Reply-To: References: Message-ID: The usual intuition behind the list Functor/Applicative/Monad instances are that they represents non-deterministic values, which can have any of some list of possible values. In this case, the natural interpretation of <|> is as a non-deterministic choice of two possible computations. So the list of possible results would include anything from either computation. Your implementation, on the other hand, would represent a left-biased choice, where the right alternative is only used if the left is impossible. It's hard to look at laws, because there's apparently little agreement on the proper laws for Alternative. It looks possible that as an Applicative and Alternative, this would be fine; but the Alternative instance you propose would work in odd ways with the Monad instance. That is, if f x == [] for any x in (non-empty) xs, then something like (xs <|> ys) >>= f would yield an empty list, while (xs >>= f) <|> (ys >>= f) would not. But, this isn't a law or anything, you could chalk it up as counter-intuitive, but not disqualifying. On Fri, May 5, 2017 at 11:12 PM, Theodore Lief Gannon wrote: > Fiddling around, I found myself wanting: > > coalesce :: [a] -> [a] -> [a] > -- or -- :: (Foldable t) => t a -> t a -> t a > coalesce a b = if null a then b else a > > I expected this to be (<|>) (it is for Maybe!) but instead I find no > canonical implementation of it anywhere, and what seems like a useless instance > Alternative []. What's the rationale? > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From headprogrammingczar at gmail.com Sat May 6 13:02:15 2017 From: headprogrammingczar at gmail.com (Joe Quinn) Date: Sat, 6 May 2017 09:02:15 -0400 Subject: [Haskell-cafe] List instance of Alternative: why (++)? In-Reply-To: References: Message-ID: <49d90ebd-d924-c872-7f8d-93d1d6f4a28f@gmail.com> The documentation for Alternative describes it as "a monoid over an applicative functor". That makes for the following documented laws for Alternative: x <|> (y <|> z) = (x <|> y) <|> z empty <|> x = x = x <|> empty This makes your coalesce a valid (<|>) if you take empty = [], but as Chris points out it's not as intuitive from the perspective of certain other nice-to-have properties. On 5/6/2017 2:36 AM, Chris Smith wrote: > The usual intuition behind the list Functor/Applicative/Monad > instances are that they represents non-deterministic values, which can > have any of some list of possible values. In this case, the natural > interpretation of <|> is as a non-deterministic choice of two possible > computations. So the list of possible results would include anything > from either computation. Your implementation, on the other hand, > would represent a left-biased choice, where the right alternative is > only used if the left is impossible. > > It's hard to look at laws, because there's apparently little agreement > on the proper laws for Alternative. It looks possible that as an > Applicative and Alternative, this would be fine; but the Alternative > instance you propose would work in odd ways with the Monad instance. > That is, if f x == [] for any x in (non-empty) xs, then something like > (xs <|> ys) >>= f would yield an empty list, while (xs >>= f) <|> (ys > >>= f) would not. But, this isn't a law or anything, you could chalk > it up as counter-intuitive, but not disqualifying. > > On Fri, May 5, 2017 at 11:12 PM, Theodore Lief Gannon > > wrote: > > Fiddling around, I found myself wanting: > > coalesce :: [a] -> [a] -> [a] > -- or -- :: (Foldable t) => t a -> t a -> t a > coalesce a b = if null a then b else a > > I expected this to be (<|>)(it is for Maybe!) but instead I find > no canonical implementation of it anywhere, and what seems like a > useless instance Alternative []. What's the rationale? > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > > > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From monkleyon at gmail.com Sat May 6 16:42:36 2017 From: monkleyon at gmail.com (MarLinn) Date: Sat, 6 May 2017 18:42:36 +0200 Subject: [Haskell-cafe] Language extension proposal: aspects Message-ID: An HTML attachment was scrubbed... URL: From monkleyon at gmail.com Sat May 6 17:14:48 2017 From: monkleyon at gmail.com (MarLinn) Date: Sat, 6 May 2017 19:14:48 +0200 Subject: [Haskell-cafe] Language extension proposal: aspects In-Reply-To: References: Message-ID: <327ab148-9061-b9db-c4c6-3b55921f2120@gmail.com> An HTML attachment was scrubbed... URL: From awede at techfak.uni-bielefeld.de Sat May 6 17:50:29 2017 From: awede at techfak.uni-bielefeld.de (Alex Wede) Date: Sat, 6 May 2017 19:50:29 +0200 Subject: [Haskell-cafe] Functor instance for FunPB Message-ID: Hey Everyone, ich have a algebraic data type: data FunPB a b = FunPB { runFunPB :: a -> (a,[b]) } I got a Monoid Instance instance Monoid (FunPB a b) where mempty = FunPB $ \k -> (k,mempty) mappend pb1 pb2 = FunPB $ \n -> (,) n $ msum . (<$>) (uncurry (flip const).((flip runFunPB) n)) $ [pb1,pb2] Now I need to write a functor instance instance Functor (FunPB a) where fmap f b = ? How can I map over a->(a,[b])? Lg Alex From monkleyon at gmail.com Sat May 6 18:25:13 2017 From: monkleyon at gmail.com (MarLinn) Date: Sat, 6 May 2017 20:25:13 +0200 Subject: [Haskell-cafe] Functor instance for FunPB In-Reply-To: References: Message-ID: <095a9931-6047-50e7-6792-c769faf83539@gmail.com> > mappend pb1 pb2 = FunPB $ \n -> (,) n $ msum . (<$>) (uncurry (flip > const).((flip runFunPB) n)) $ [pb1,pb2] This cracks me up. Well played. Well played indeed. Well all the things you need are right here in this line, right? I mean you sent it because you want to show us what you know, right? There's higher order functions, there's mapping and folding and currying of different kinds and everything. So what's missing? From ruben.astud at gmail.com Sat May 6 18:30:47 2017 From: ruben.astud at gmail.com (Ruben Astudillo) Date: Sat, 6 May 2017 15:30:47 -0300 Subject: [Haskell-cafe] Functor instance for FunPB In-Reply-To: References: Message-ID: <45dc19bb-6f83-13c5-e0e9-9d12ed9da138@gmail.com> On 06/05/17 14:50, Alex Wede wrote: > Now I need to write a functor instance > > instance Functor (FunPB a) where > > fmap f b = ? It will help to see the specific types of the instance instance Functor (FunPB a) where fmap :: (c -> d) -> FunPB a c -> FunPB a d ie we need to change only the second argument of FunPB a c. By you definition, that would be the [b] in data FunPB a b = FunPB { runFunPB :: a -> (a,[b]) } so you can remove the constructor to get the inner function, create a new function that uses the inner one and fmap the second part of the tuple instance Functor (FunPB a) where fmap f (FunPB lambda) = FunPB $ \a1 -> let (a2, bs) = lambda a1 in (a2 , fmap f bs) see that we have a `fmap f bs` in the second part, we use that we already have a Functor instance for [b], making our job easier. -- -- Ruben From awede at techfak.uni-bielefeld.de Sat May 6 18:32:45 2017 From: awede at techfak.uni-bielefeld.de (Alex Wede) Date: Sat, 6 May 2017 20:32:45 +0200 Subject: [Haskell-cafe] Functor instance for FunPB In-Reply-To: <095a9931-6047-50e7-6792-c769faf83539@gmail.com> References: <095a9931-6047-50e7-6792-c769faf83539@gmail.com> Message-ID: <14cfab07-a74f-b97a-6f99-62dce5954719@techfak.uni-bielefeld.de> Hey, No, I do not want to show anything. The monoid instance is from my teacher. It is an exercise. Sry for the misunderstanding. LG Alex Am 06.05.2017 um 20:25 schrieb MarLinn: > >> mappend pb1 pb2 = FunPB $ \n -> (,) n $ msum . (<$>) (uncurry (flip >> const).((flip runFunPB) n)) $ [pb1,pb2] > > This cracks me up. Well played. Well played indeed. > > Well all the things you need are right here in this line, right? I > mean you sent it because you want to show us what you know, right? > There's higher order functions, there's mapping and folding and > currying of different kinds and everything. So what's missing? > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From kane at kane.cx Sat May 6 18:38:13 2017 From: kane at kane.cx (David Kraeutmann) Date: Sat, 6 May 2017 20:38:13 +0200 Subject: [Haskell-cafe] Functor instance for FunPB In-Reply-To: References: Message-ID: The only lawful instance I can think of is: instance Functor (FunPB a) where fmap f (FunPB g) = FunPB $ \k -> let (a,b) = g k in (a, fmap f b) which is fairly straightforward IMO. On 2017-05-06 19:50, Alex Wede wrote: > Hey Everyone, > > > ich have a algebraic data type: > > > data FunPB a b = FunPB { runFunPB :: a -> (a,[b]) } > > > I got a Monoid Instance > > instance Monoid (FunPB a b) where > mempty = FunPB $ \k -> (k,mempty) > mappend pb1 pb2 = FunPB $ \n -> (,) n $ msum . (<$>) (uncurry (flip > const).((flip runFunPB) n)) $ [pb1,pb2] > > Now I need to write a functor instance > > instance Functor (FunPB a) where > > fmap f b = ? > > > How can I map over a->(a,[b])? > > > Lg > > Alex > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From ruben.astud at gmail.com Sat May 6 18:43:09 2017 From: ruben.astud at gmail.com (Ruben Astudillo) Date: Sat, 6 May 2017 15:43:09 -0300 Subject: [Haskell-cafe] Language extension proposal: aspects In-Reply-To: <327ab148-9061-b9db-c4c6-3b55921f2120@gmail.com> References: <327ab148-9061-b9db-c4c6-3b55921f2120@gmail.com> Message-ID: <3244be04-b166-ad7f-6cdc-12f0352489f6@gmail.com> On 06/05/17 14:14, MarLinn wrote: > Here is a more complete example without my ramblings to disturb you. Imagine the > code being distributed across three files. > > --- > aspect Data.Aspect.Bool.All where > > instance Monoid Bool where > mempty = True > mappend False _ = False > mappend True b = b > > --- > aspect Data.Aspect.Bool.Any where > > instance Monoid Bool where > mempty = False > mappend True _ = True > mappend False b = b how would this interact with superclasses class Monoid m => Newclass m As I understand the proposal, you got default instances. But how do you extend with the alternative instance? by you examples with foldMap you would need to extend the data type with the aspect you mean to do it, well that is exactly what newtypes are! thus far I don't see any benefits of making it less explicit. -- -- Ruben From mail at joachim-breitner.de Sat May 6 18:45:34 2017 From: mail at joachim-breitner.de (Joachim Breitner) Date: Sat, 06 May 2017 14:45:34 -0400 Subject: [Haskell-cafe] Functor instance for FunPB In-Reply-To: <14cfab07-a74f-b97a-6f99-62dce5954719@techfak.uni-bielefeld.de> References: <095a9931-6047-50e7-6792-c769faf83539@gmail.com> <14cfab07-a74f-b97a-6f99-62dce5954719@techfak.uni-bielefeld.de> Message-ID: <1494096334.23037.4.camel@joachim-breitner.de> Hi, Am Samstag, den 06.05.2017, 20:32 +0200 schrieb Alex Wede: > The monoid instance is from my teacher. it is hard to tell with confidence, given that we do not know what FunFB is supposed to “mean”, but data FunPB a b = FunPB { runFunPB :: a -> (a,[b]) } instance Monoid (FunPB a b) where    mempty  = FunPB $ \k -> (k,mempty)    mappend pb1 pb2 = FunPB $ \n -> (,) n $ msum . (<$>) (uncurry (flip const).((flip runFunPB) n)) $ [pb1,pb2] looks very fishy, as the return value of of type a from pb1 and pb2 are ignored in mappend The latter means that this is not a lawful monoid, because for pb = (\n -> (n+1, []) we have mempty `mappend` pb == mempty /= pb Did you maybe mean    mappend pb1 pb2 = FunPB  $ \n0 -> let (n1,xs1) = runFunFB n1 (n2,xs2) = runFunFB n2 in (n2, xs1 ++ xs2) Greetings, Joachim -- Joachim Breitner mail at joachim-breitner.de http://www.joachim-breitner.de/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: This is a digitally signed message part URL: From monkleyon at gmail.com Sat May 6 19:04:40 2017 From: monkleyon at gmail.com (MarLinn) Date: Sat, 6 May 2017 21:04:40 +0200 Subject: [Haskell-cafe] Functor instance for FunPB In-Reply-To: References: Message-ID: <0ad8fafa-7fc6-febc-002b-b3b38a36f8d7@gmail.com> On 2017-05-06 20:38, David Kraeutmann wrote: > The only lawful instance I can think of is: > instance Functor (FunPB a) where > fmap f (FunPB g) = FunPB $ \k -> let (a,b) = g k in (a, fmap f b) > > which is fairly straightforward IMO. And because it's closer to the original style: fmap f = FunPB .((.)((<$>).(<$>)$f)). runFunPB Now it's STARRING INTO YOU SOUL. And it's also so much easier to read. From olshanskydr at gmail.com Sat May 6 19:37:22 2017 From: olshanskydr at gmail.com (Dmitry Olshansky) Date: Sat, 6 May 2017 22:37:22 +0300 Subject: [Haskell-cafe] Language extension proposal: aspects In-Reply-To: References: Message-ID: How does compiler can infer a type for "allEven = foldMap even" ? Something like allEven :: (Monoid (aspect Bool), Integral a) => [a] -> Bool ? Should all Bool's in function body have the same aspects? 2017-05-06 19:42 GMT+03:00 MarLinn : > Hi people, > > in the last couple days this list has once again seen examples of how our > class system is not perfect yet. Here are some of the problems we face: > > - Useful, but confusing instances like Foldable ((,) a) > - Alternative possible instances like Alternative [] > - Orphan instances > - Reliance on the order of arguments makes some instances impossible, > for example Traversable (,a) > > How we usually resolve some of such issues is with newtype. Among the > drawbacks are > > - This clutters code with artificial wrappers and unwrappers that have > nothing to do with the task at hand > - It implies two levels of hierarchy by marking the one instance > without a newtype as special > - Every type needs its own wrapper. E.g. a Foldable (,a) (if possible) > would need a different wrapper from a Foldable (a,,c) > - Definitions are scattered at unexpected places, like All and Any, > partly to avoid orphan instances. > > After some thought I therefore propose a language extension I call > "aspects". Keep in mind that this is a very rough draft just to gauge your > reaction. > > The core change would be the introduction of a keyword "aspect" that > would work in a comparable way to the keyword "module". In other words > you could say > > aspect Data.Aspect.ChooseNonEmpty where > > import qualified Data.Set as Set > > instance Alternative [] where > empty = [] > a <|> b = if null a then b else a > > instance Alternative Set.Set where … > empty = Set.empty > a <|> b = if null a then b else a > > Changes compared to a normal module would be: > > - An aspect can only contain instances > - An aspect can import anything, but exports only instances > - An aspect will never produce orphan instance warnings (duh.) > - An aspect can be a file level definition, but it can also be > contained in a module (we'll see why that is useful) > > You also wouldn't import an aspect like a normal module, but with a second > syntax extension: > > import Data.List under (Data.Aspect.ChooseNonEmpty) > import qualified Data.Set as Set hiding (Set) > import qualified Data.Set under (Default, Data.Aspect.ChooseNonEmpty) as CNE (Set) > > So you could also import the same structure twice with different aspects > under different names: > > import Data.Bool > import qualified Data.Bool under (Data.Aspect.All) as All (Bool) > import qualified Data.Bool under (Data.Aspect.Any) as Any (Bool) > > Now, because of the first import, you could use the boolean functions > normally, and even use the normal Bool type in signatures. And because of > the qualified imports if you want to use one of the Monoid instances, all > you would have to do is change Bool in the type signature to Any.Bool or > All.Bool respectively, like so: > > allEven :: (Integral a) => [a] -> Bool > allEven = foldMap even -- error: Could not deduce (Monoid Bool)… > > -- old way > allEven :: (Integral a) => [a] -> Bool > allEven = getAll . foldMap (All . even) > > -- new way > allEven :: (Integral a) => [a] -> All.Bool -- qualified name adds the monoidal aspect (and possibly others) > allEven = foldMap even -- works > > In other words, aspects would only be used for instance lookups. That is > also why you could state several aspects at once when importing. Conflicts > would be solved as usual: All is well until you try to use class functions > that create an ambiguity. > > I imagine a few special rules to make backwards compatibility easier. Most > importantly, you could define default aspects in several ways: > > - aspect Default where … -- reserved aspect name > - default aspect ChooseNonEmpty where … -- re-used reserved keyword, > but also gives a name to the aspect > - default aspect where … -- short form for default > aspect Default where … > - An instance defined in a module outside of an aspect would > automatically be in the Default aspect. In other words the definition > can be seen as a short form of a local extension to the aspect. That's also > why aspects would be allowed to be part of a module. > > If you don't specify an aspect while importing, it would be imported under > the Default aspect. To hide the Default aspect, just don't add it to the > aspect list when importing. > > Other random thoughts about this: > > - An aspect doesn't need to be complete. E.g. I imagine an aspect that > only defines Alternative.empty, with several other aspects relying on > that by importing this incomplete aspect. OO programmers might call them > abstract aspects. This might possibly help resolve some disputes about the > "perfect" hierarchy. > - If aspects can be part of a module, can aspects also be part of an > aspect? Maybe, but I haven't made a cost-benefit analysis yet. > - Aspects seem to form a level of container between definitions and > modules. Maybe there should also be a new container type (or several) for > the other parts of code? Say, a container that can contain everything > *but* instances. > - There could be an extension to the export syntax to choose which > aspects to export. I just don't see the usefulness right now. > - There could also be special syntax like import * under > (Default,SpecialAspect) as a short form to add some aspects to every > imported module. > - The Default aspect is obviously extensible. I consider that a > universally useful, if not essential feature. On the other hand in this > proposal aspects use the module name space – which means such extensions > would only be possible on a package level or by using several code folder > roots. I'm not sure I'm happy with that. > - The proposal doesn't solve the issue that instances rely the order > of arguments. But an introduction of such new syntax might be a good time > to introduce two extensions at once. I imagine something like instance > Foldable (,) _ a where… > > The biggest drawbacks from this idea that I can see right now are: > > - The language extension might be infectious: once one library in a > project uses it, many parts of the project might need it. This is different > from most extensions that stay rather local. > - Such a change might necessitate huge amounts of cpp. > - Because aspects would be extensible and would have a global name > space, care would have to be taken to not create a mess. > > So… feel free to bikeshed and more importantly criticize! What am I > overlooking? Would you consider such an idea worthwhile? Happy to hear your > thoughts. > > Cheers, > MarLinn > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dhelta.diaz at gmail.com Sat May 6 19:37:24 2017 From: dhelta.diaz at gmail.com (=?UTF-8?Q?Daniel_D=C3=ADaz_Casanueva?=) Date: Sat, 6 May 2017 21:37:24 +0200 Subject: [Haskell-cafe] Functor instance for FunPB In-Reply-To: <0ad8fafa-7fc6-febc-002b-b3b38a36f8d7@gmail.com> References: <0ad8fafa-7fc6-febc-002b-b3b38a36f8d7@gmail.com> Message-ID: Hallo. You can try reusing fmap. >>> data FunPB a b = FunPB { runFunPB :: a -> (a,[b]) fmap f (FunPB g) = FunPB $ fmap (fmap (fmap f)) g >>> This works because (a->), (a,), and [] are all functors. Freundliche Grüße, Daniel. On Sat, May 6, 2017 at 9:04 PM, MarLinn wrote: > > On 2017-05-06 20:38, David Kraeutmann wrote: > >> The only lawful instance I can think of is: >> instance Functor (FunPB a) where >> fmap f (FunPB g) = FunPB $ \k -> let (a,b) = g k in (a, fmap f b) >> >> which is fairly straightforward IMO. >> > And because it's closer to the original style: > > fmap f = FunPB .((.)((<$>).(<$>)$f)). runFunPB > > Now it's STARRING INTO YOU SOUL. And it's also so much easier to read. > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From monkleyon at gmail.com Sat May 6 20:01:22 2017 From: monkleyon at gmail.com (MarLinn) Date: Sat, 6 May 2017 22:01:22 +0200 Subject: [Haskell-cafe] Language extension proposal: aspects In-Reply-To: <3244be04-b166-ad7f-6cdc-12f0352489f6@gmail.com> References: <327ab148-9061-b9db-c4c6-3b55921f2120@gmail.com> <3244be04-b166-ad7f-6cdc-12f0352489f6@gmail.com> Message-ID: Thanks for the feedback! >> aspect Data.Aspect.Bool.Any where >> >> instance Monoid Bool where >> mempty = False >> mappend True _ = True >> mappend False b = b > how would this interact with superclasses > > class Monoid m => Newclass m Aspects wouldn't care about superclasses directly. That's still the role of the instance declaration. But aspects – like normal modules – would be able to choose under which aspects to import their own dependencies. So in this way they would be able to "choose" their line of heritage. Of course if you import an aspect, you would also get all that heritage. > As I understand the proposal, you got default instances. Mostly as a convenience and for backwards compatibility, but yes, in the form of the Default aspect. In fact every single instance we have now would initially be a "default instance" in the new model, by implicitly being in that aspect. It would probably be a good idea to move at least some of them to dedicated aspects though. The class system itself would be unchanged, including the defaulting and inheritance rules. But you would be able to drop the default instances by dropping the default aspect. You just would have to be aware that you'd be dropping all the default instances for the whole hierarchy of this constructor. > But how do you extend with the alternative instance? by you examples with foldMap you would need to extend the data type with the aspect you mean to do it, well that is exactly what newtypes are! thus far I don't see any benefits of making it less explicit. I would have to implement the second instance in a second aspect, just without all the wrapping we do now. So yes, on first sight my proposed solution really offers little functionality that newtypes don't. But I claim the results already look much cleaner and should lead to more readable code. I also expect there might be bigger benefits to come from the separation of concerns and when you're able to just inherit big chunks of theory. Imagine that instead of injecting lots of Sum and getSum deep into a structure you could just add one type signature via proxy. Imagine extending the Sum aspect to elaborate on what the concept of "summation" really means instead of being stuck in the Num hierarchy. Why have All/Any and Sum/Product separately when they really describe the same basic concept? Why have Data.Ord.Down and Control.Applicative.Backwards when the underlying idea is exactly the same? Also, it's such a simple idea but how many would even think to look for these newtypes here? And do you know if there is a similar newtype for Foldable? Where would you look? If there is one aspect, just look into this aspect, done. That's what I really want aspects to describe: mathematical concepts that we use over and over, independently from the concrete types. Hope I was able to answer some questions? Cheers, MarLinn From monkleyon at gmail.com Sat May 6 20:55:21 2017 From: monkleyon at gmail.com (MarLinn) Date: Sat, 6 May 2017 22:55:21 +0200 Subject: [Haskell-cafe] Language extension proposal: aspects In-Reply-To: References: Message-ID: <670697a8-e2ea-3af8-d8e0-862ffc489562@gmail.com> On 2017-05-06 21:37, Dmitry Olshansky wrote: > How does compiler can infer a type for "allEven = foldMap even" ? > > Something like > allEven :: (Monoid (aspect Bool), Integral a) => [a] -> Bool ? I hadn't thought about inference actually. But even if the compiler inferred a type, it would still fail with a missing constraint. So I don't strongly care what the implied constraint is, as long as the error message is comprehensible. Maybe it could mention aspects in the future, but that's not even necessary. So basically the inferred type would just be allEven :: (Monoid Bool, Integral a) => [a] -> Bool The compiler would just know "I need a Monoid instance for Bool!" as it does right now. And just as now, it knows where to look – the only difference is that with my proposal that place to look has a different name. > Should all Bool's in function body have the same aspects? Yes, if the aspect comes from a type signature. If the type signature is local, it would be local to its region of application. For example: --- module Test where import qualified Data.Bool under (Default, Data.Aspect.Bool.All) as A_All_ (Bool) import qualified Data.Bool under (Default, Data.Aspect.Bool.Any) as A_Any_ (Bool) test2 :: (Integral a) => [a] -> Bool test2 xs = (foldMap even xs :: A_All_.Bool) == not (foldMap odd xs :: A_Any_.Bool) The type is imported twice with different names and under different aspects. The local type signatures use these names to define which are the right instances. An alternative would be something like test2 :: (Integral a) => [a] -> Bool test2 xs = (foldMap even xs :: (Bool under A_All_)) == not (foldMap odd xs :: (Bool under A_Any_)) which would make the aspect-nature clearer. But I didn't want to introduce even more syntax, especially as the naming scheme is already enough. Was that clarifying? I have to say, your questions did make me ponder how much of my proposal would already be possible by exploiting type families. I'm not sure yet, but I'll think about it. So thanks! Cheers, MarLinn From twhitehead at gmail.com Sat May 6 21:40:17 2017 From: twhitehead at gmail.com (Tyson Whitehead) Date: Sat, 6 May 2017 17:40:17 -0400 Subject: [Haskell-cafe] Generalized concatMap for lenses? Message-ID: <26818156-2ba4-86ae-19cc-8ef7badbe328@gmail.com> I am writing some code to do some web-page parsing using the lens library. The folded (or traverse) functions let me go sequence -> lens fold It would be nice to be able to go back again lens fold -> sequence The general idea being move it into a lens-fold sequence representation, work with it there, and then recover the original sequence representation. As a more concrete example, the following works for lists (folded .) :: Getter s [a] -> Fold s a (to . toListOf) :: Fold s a -> Getter s [a] I think I'm maybe thinking of something like a generalized concatMap for lenses magic :: Fold s a -> Getter (f s) (f a) Possibly there is already a function for this or some other way it should be done? Haven't found it yet though, so thought I would ask the list for some enlightenment. Thanks! -Tyson From evincarofautumn at gmail.com Sat May 6 22:23:41 2017 From: evincarofautumn at gmail.com (Jon Purdy) Date: Sat, 6 May 2017 15:23:41 -0700 Subject: [Haskell-cafe] List instance of Alternative: why (++)? In-Reply-To: References: Message-ID: I’ve wanted this before as well. Maybe we should throw a newtype at it? newtype LeftBiased a = LeftBiased [a] instance Alternative (LeftBiased a) where empty = [] [] <|> b = b a <|> _ = a newtype RightBiased a = RightBiased [a] instance Alternative (RightBiased a) where empty = [] a <|> [] = a _ <|> b = b This could be generalised to work on any Foldable, actually, if that’s desirable. And of course the bikeshed could be a different colour as for the names. It’s unfortunate that the instance for Maybe is already biased differently; I wonder if this instance would be useful, or if it’s already available somewhere? newtype Unbiased a = Unbiased (Maybe a) instance (Monoid m) => Alternative (Unbiased m) where empty = Nothing Just a <|> Just b = Just (a <> b) _ <|> Just b = Just b Just a <|> _ = Just a _ <|> _ = Nothing On Fri, May 5, 2017 at 11:12 PM, Theodore Lief Gannon wrote: > Fiddling around, I found myself wanting: > > coalesce :: [a] -> [a] -> [a] > -- or -- :: (Foldable t) => t a -> t a -> t a > coalesce a b = if null a then b else a > > I expected this to be (<|>) (it is for Maybe!) but instead I find no > canonical implementation of it anywhere, and what seems like a useless instance > Alternative []. What's the rationale? > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From monkleyon at gmail.com Sat May 6 23:19:17 2017 From: monkleyon at gmail.com (MarLinn) Date: Sun, 7 May 2017 01:19:17 +0200 Subject: [Haskell-cafe] List instance of Alternative: why (++)? In-Reply-To: References: Message-ID: An HTML attachment was scrubbed... URL: From 14 at mniip.com Sat May 6 23:24:33 2017 From: 14 at mniip.com (mniip) Date: Sun, 7 May 2017 02:24:33 +0300 Subject: [Haskell-cafe] Partial type family application In-Reply-To: <20170426122932.GA19211@mniip.com> References: <20170426122421.GB17944@mniip.com> <20170426122932.GA19211@mniip.com> Message-ID: <20170506232433.GA24832@mniip.com> For everyone who didn't notice, the original post was incorporated into this proposal: https://github.com/ghc-proposals/ghc-proposals/pull/52 which attracted less community attention than I hoped it would. Please check it out! On Wed, Apr 26, 2017 at 03:29:32PM +0300, mniip wrote: > This idea is very fresh, and I certainly haven't explored all the > aspects, so I would welcome constructive (and intuitionistic) criticism > regarding both usefulness and mathematical soundness of this. --mniip From tanuki at gmail.com Sun May 7 03:19:21 2017 From: tanuki at gmail.com (Theodore Lief Gannon) Date: Sat, 6 May 2017 20:19:21 -0700 Subject: [Haskell-cafe] Language extension proposal: aspects In-Reply-To: <670697a8-e2ea-3af8-d8e0-862ffc489562@gmail.com> References: <670697a8-e2ea-3af8-d8e0-862ffc489562@gmail.com> Message-ID: Namespace notation might not be optimal, because it's not clear at a glance that this is an aspect and not a regular qualified import of a type (an important distinction if you have multiple versions of the same type imported, e.g. Bytestring). Why not make it look like type application instead? Modifying your example: allEven :: (Integral a) => [a] -> Bool at A_All_ And for that matter, I'd rather not be forced to write a signature (what if I want to use this in a where clause?) So... does this break anything? allEven = foldMap at A_All_ even Which means, for this invocation of foldMap, instances within A_All_ are in effect for all of its constraints. You could chain multiple @'s together so long as they don't produce any relevant overlapping instances. To avoid surprises, they shouldn't propagate -- when foldMap invokes even, it sees the default Monoid instance for Bool (i.e. none). If it were also a function that needs a Monoid, you'd need another @. There's potential for boilerplate here. Falling back to doing it in the type signature could force propagation? I'm not sure it's ever a safe idea, though. On Sat, May 6, 2017 at 1:55 PM, MarLinn wrote: > On 2017-05-06 21:37, Dmitry Olshansky wrote: > >> How does compiler can infer a type for "allEven = foldMap even" ? >> >> Something like >> allEven :: (Monoid (aspect Bool), Integral a) => [a] -> Bool ? >> > > I hadn't thought about inference actually. But even if the compiler > inferred a type, it would still fail with a missing constraint. So I don't > strongly care what the implied constraint is, as long as the error message > is comprehensible. Maybe it could mention aspects in the future, but that's > not even necessary. So basically the inferred type would just be > > allEven :: (Monoid Bool, Integral a) => [a] -> Bool > > The compiler would just know "I need a Monoid instance for Bool!" as it > does right now. And just as now, it knows where to look – the only > difference is that with my proposal that place to look has a different name. > > Should all Bool's in function body have the same aspects? >> > > Yes, if the aspect comes from a type signature. If the type signature is > local, it would be local to its region of application. For example: > > --- > module Test where > > import qualified Data.Bool under (Default, Data.Aspect.Bool.All) as > A_All_ (Bool) > import qualified Data.Bool under (Default, Data.Aspect.Bool.Any) as > A_Any_ (Bool) > > test2 :: (Integral a) => [a] -> Bool > test2 xs = (foldMap even xs :: A_All_.Bool) == not (foldMap odd xs :: > A_Any_.Bool) > > The type is imported twice with different names and under different > aspects. The local type signatures use these names to define which are the > right instances. > > An alternative would be something like > > test2 :: (Integral a) => [a] -> Bool > test2 xs = (foldMap even xs :: (Bool under A_All_)) == not (foldMap > odd xs :: (Bool under A_Any_)) > > which would make the aspect-nature clearer. But I didn't want to introduce > even more syntax, especially as the naming scheme is already enough. > > Was that clarifying? > > I have to say, your questions did make me ponder how much of my proposal > would already be possible by exploiting type families. I'm not sure yet, > but I'll think about it. So thanks! > > > Cheers, > MarLinn > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From clintonmead at gmail.com Sun May 7 04:19:01 2017 From: clintonmead at gmail.com (Clinton Mead) Date: Sun, 7 May 2017 14:19:01 +1000 Subject: [Haskell-cafe] Constraining constraints Message-ID: I posted the following on stackoverflow , but it hasn't got too much attention so I thought I'd ask here: I can write the following: {-# LANGUAGE RankNTypes #-}{-# LANGUAGE FlexibleInstances #-}{-# LANGUAGE UndecidableInstances #-}{-# LANGUAGE ConstraintKinds #-} f :: Integral a => (forall b. Num b => b) -> a f = id And all is good. Presumably GHC can derive Integral from Num so all is well. I can be a bit tricker, yet I'm still fine: class Integral x => MyIntegral xinstance Integral x => MyIntegral x class Num x => MyNum xinstance Num x => MyNum x f' :: MyIntegral a => (forall b. MyNum b => b) -> a f' = id So lets say I want to generalise this, like so: g :: c2 a => (forall b. c1 b => b) -> a g = id Now obviously this will spit the dummy, because GHC can not derive c2 from c1, as c2 is not constrained. What do I need to add to the type signature of g to say that "you can derive c2 from c1"? -------------- next part -------------- An HTML attachment was scrubbed... URL: From evincarofautumn at gmail.com Sun May 7 07:23:15 2017 From: evincarofautumn at gmail.com (Jon Purdy) Date: Sun, 7 May 2017 00:23:15 -0700 Subject: [Haskell-cafe] List instance of Alternative: why (++)? In-Reply-To: References: Message-ID: D’oh, that’s what I get for writing untested code in an email. Neutral doesn’t seem necessary since we have “null” in Foldable. I was thinking more along these lines: instance (Alternative f, Foldable f) => Alternative (LeftBiased f) where empty = LeftBiased empty LeftBiased a <|> LeftBiased b = LeftBiased (if null a then b else a) Under the assumption that “null empty” always holds. I think using the Alternative constraint for just “empty” makes sense because LeftBiased and RightBiased should only differ from the wrapped type in the implementation of (<|>), but it still seems a little iffy somehow. To make the wrapping slightly less painful, another good bikeshed colour would be Pre/Post. (Dunno what you’d call “Unbiased” in that case, though.) On a related note, I recall there was some discussion a while back about making a Monoid instance for Map where mappend is “unionWith mappend” instead of the left-biased “union”. These wrappers could also be used for that sort of thing, and it’d be nice to have a single standard for them with all the different use cases fleshed out. On Sat, May 6, 2017 at 4:19 PM, MarLinn wrote: > > On 2017-05-07 00:23, Jon Purdy wrote: > > I’ve wanted this before as well. Maybe we should throw a newtype at it? > > newtype LeftBiased a = LeftBiased [a] > instance Alternative (LeftBiased a) where > empty = [] > [] <|> b = b > a <|> _ = a > > newtype RightBiased a = RightBiased [a] > instance Alternative (RightBiased a) where > empty = [] > a <|> [] = a > _ <|> b = b > > You forgot the fun wrapping and unwrapping. But no matter. Let's > generalize! > > class Neutral a where > neutral :: a > isNeutral :: a -> Bool > > instance Neutral a => Alternative (LeftBiased a) where > empty = LeftBiased neutral > (LeftBiased a) <|> (LeftBiased b) = LeftBiased $ if isNeutral a then b else a > > instance Neutral a => Alternative (RightBiased a) where > empty = RightBiased neutral > (RightBiased a) <|> (RightBiased b) = RightBiased $ if isNeutral b then a else b > > Why? > > type AllRight e a = LeftBiased (Either e a) > type AnyRight e a = RightBiased (Either e a) > > instance Neutral a => Neutral (AllRight e a) where > neutral = Right $ LeftBiased neutral > isNeutral = fmap isRight > > instance Neutral e => Neutral (AnyRight e a) where > neutral = Left $ RightBiased neutral > isNeutral = fmap isLeft > > Is this a bit silly? Yes. My actual goal is to show that these concepts > are bigger than they might appear, and how painful all those wrappers are. > This is to advertise my language extension from my separate thread. And > also because it's silly fun. Mostly that. > > > newtype Unbiased a = Unbiased (Maybe a) > instance (Monoid m) => Alternative (Unbiased m) where > empty = Nothing > Just a <|> Just b = Just (a <> b) > _ <|> Just b = Just b > Just a <|> _ = Just a > _ <|> _ = Nothing > > Mh, that's just liftA2 (<>) a b <|> a <|> b in terms of the regular > instance. Now that is easy to generalize – just don't use it for lists. > Cheers, > MarLinn > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ivan.miljenovic at gmail.com Sun May 7 07:40:09 2017 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Sun, 7 May 2017 17:40:09 +1000 Subject: [Haskell-cafe] Constraining constraints In-Reply-To: References: Message-ID: On 7 May 2017 at 14:19, Clinton Mead wrote: > I posted the following on stackoverflow, but it hasn't got too much > attention so I thought I'd ask here: > > I can write the following: > > {-# LANGUAGE RankNTypes #-} > {-# LANGUAGE FlexibleInstances #-} > {-# LANGUAGE UndecidableInstances #-} > {-# LANGUAGE ConstraintKinds #-} > > f :: Integral a => (forall b. Num b => b) -> a > f = id > > And all is good. Presumably GHC can derive Integral from Num so all is well. > > I can be a bit tricker, yet I'm still fine: > > class Integral x => MyIntegral x > instance Integral x => MyIntegral x > > class Num x => MyNum x > instance Num x => MyNum x > > f' :: MyIntegral a => (forall b. MyNum b => b) -> a > f' = id This one I'm not that sure about. Ignore the actual instances you've provided (since IIRC GHC doesn't actually look at those for constraints, just the class definition). Whilst any MyIntegral is an Integral and hence a Num, and likewise any MyNum is a Num, it doesn't mean that something that creates a MyNum will be able to create a MyIntegral (e.g. MyNum ~ Floating and you pass in pi as the value in the forall). > > So lets say I want to generalise this, like so: > > g :: c2 a => (forall b. c1 b => b) -> a > g = id > > Now obviously this will spit the dummy, because GHC can not derive c2 from > c1, as c2 is not constrained. > > What do I need to add to the type signature of g to say that "you can derive > c2 from c1"? > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -- Ivan Lazar Miljenovic Ivan.Miljenovic at gmail.com http://IvanMiljenovic.wordpress.com From olshanskydr at gmail.com Sun May 7 09:21:06 2017 From: olshanskydr at gmail.com (Dmitry Olshansky) Date: Sun, 7 May 2017 12:21:06 +0300 Subject: [Haskell-cafe] Language extension proposal: aspects In-Reply-To: <670697a8-e2ea-3af8-d8e0-862ffc489562@gmail.com> References: <670697a8-e2ea-3af8-d8e0-862ffc489562@gmail.com> Message-ID: If we have allEven :: (Monoid Bool, Integral a) => [a] -> Bool then, as usual, we have to define an aspect for Bool on the caller's side. So there are two possibilities for user: - fix an aspect in the function, there is no need for aspect on caller side (What will be if on the caller side we already have an another aspect?! Probably we can ignore it...) - aspect-oriented constraint in the function's signature and fix an aspect for the caller I think that the second case is more useful. We prefer to write generalized functions! But in this case I'm afraid that we end-up with the same noise as for the newtype. But instead of construct to and deconstruct from newtype we will have to define aspects on type level for caller and define constraint for function. Usually type-level syntax is more complicated... 2017-05-06 23:55 GMT+03:00 MarLinn : > On 2017-05-06 21:37, Dmitry Olshansky wrote: > >> How does compiler can infer a type for "allEven = foldMap even" ? >> >> Something like >> allEven :: (Monoid (aspect Bool), Integral a) => [a] -> Bool ? >> > > I hadn't thought about inference actually. But even if the compiler > inferred a type, it would still fail with a missing constraint. So I don't > strongly care what the implied constraint is, as long as the error message > is comprehensible. Maybe it could mention aspects in the future, but that's > not even necessary. So basically the inferred type would just be > > allEven :: (Monoid Bool, Integral a) => [a] -> Bool > > The compiler would just know "I need a Monoid instance for Bool!" as it > does right now. And just as now, it knows where to look – the only > difference is that with my proposal that place to look has a different name. > > Should all Bool's in function body have the same aspects? >> > > Yes, if the aspect comes from a type signature. If the type signature is > local, it would be local to its region of application. For example: > > --- > module Test where > > import qualified Data.Bool under (Default, Data.Aspect.Bool.All) as > A_All_ (Bool) > import qualified Data.Bool under (Default, Data.Aspect.Bool.Any) as > A_Any_ (Bool) > > test2 :: (Integral a) => [a] -> Bool > test2 xs = (foldMap even xs :: A_All_.Bool) == not (foldMap odd xs :: > A_Any_.Bool) > > The type is imported twice with different names and under different > aspects. The local type signatures use these names to define which are the > right instances. > > An alternative would be something like > > test2 :: (Integral a) => [a] -> Bool > test2 xs = (foldMap even xs :: (Bool under A_All_)) == not (foldMap > odd xs :: (Bool under A_Any_)) > > which would make the aspect-nature clearer. But I didn't want to introduce > even more syntax, especially as the naming scheme is already enough. > > Was that clarifying? > > I have to say, your questions did make me ponder how much of my proposal > would already be possible by exploiting type families. I'm not sure yet, > but I'll think about it. So thanks! > > > Cheers, > MarLinn > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From andrew.gibiansky at gmail.com Sun May 7 15:50:24 2017 From: andrew.gibiansky at gmail.com (Andrew Gibiansky) Date: Sun, 07 May 2017 15:50:24 +0000 Subject: [Haskell-cafe] Seeking Help with IHaskell Maintenance/Development Message-ID: Hey folks, For the past several months, I have not been able to put any effort into maintaining IHaskell, a front-end for Jupyter for Haskell. I do not know how useful IHaskell has been in the past to the community, but as it becomes more and more outdated it becomes less useful. If anyone is interested in helping out (or taking over) IHaskell maintenance and development, please let me know. Best, Andrew -- – Andrew -------------- next part -------------- An HTML attachment was scrubbed... URL: From jkarni at gmail.com Sun May 7 16:37:06 2017 From: jkarni at gmail.com (Julian K. Arni) Date: Sun, 7 May 2017 18:37:06 +0200 Subject: [Haskell-cafe] [ANN] ble: Bluetooth Low Energy in Haskell Message-ID: <20170507163706.oh7kku3cyb6astr3@Tal> Dear list, I've released the package 'ble' a little while ago, but hadn't announced it so far because I wanted to make sure the API stabilized somewhat, and at least some bugs were addressed, in the course of dealing with our own needs. But now feels like a good time to announce it. 'ble' allows writing Bluetooth Low Energy peripherals in Haskell (and soon, centrals too). Currently only Linux (with Bluez >= 5.41) is supported. Mostly it exposes the GATT API. The README (in the github repo and in the Hackage main page) provide a simple example application. Github: https://github.com/plow-technologies/ble Hackage: http://hackage.haskell.org/package/ble Enjoy, ~~~ Julian Arni Haskell Consultant https://turingjump.com/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 455 bytes Desc: not available URL: From jhwheaton at gmail.com Sun May 7 18:05:10 2017 From: jhwheaton at gmail.com (Jonathan Wheaton) Date: Sun, 7 May 2017 14:05:10 -0400 Subject: [Haskell-cafe] Seeking Help with IHaskell Maintenance/Development In-Reply-To: References: Message-ID: As a Haskell newbie and someone who uses IHaskell as a way of exploring Haskell from anywhere (work, various laptops and Chromebooks at home, my mobile phone even), I would be really sad to see IHaskell go away. I'm very much hoping the project can find a maintainer, as it's been invaluable to me. Jonathan Wheaton On May 7, 2017 11:52 AM, "Andrew Gibiansky" wrote: Hey folks, For the past several months, I have not been able to put any effort into maintaining IHaskell, a front-end for Jupyter for Haskell. I do not know how useful IHaskell has been in the past to the community, but as it becomes more and more outdated it becomes less useful. If anyone is interested in helping out (or taking over) IHaskell maintenance and development, please let me know. Best, Andrew -- – Andrew _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From erkokl at gmail.com Mon May 8 03:25:44 2017 From: erkokl at gmail.com (Levent Erkok) Date: Sun, 7 May 2017 20:25:44 -0700 Subject: [Haskell-cafe] [ANN] New release of SBV, now with optimization Message-ID: I'm happy to announce a new release of SBV (v6.0); a library for seamlessly integrating SMT solvers with Haskell: http://hackage.haskell.org/package/sbv This version brings optimization features to SBV, where arithmetic goals can be minimized or maximized. The algorithms employed are particularly suitable for linear-optimization problems, over bounded/unbounded integers and reals. Multiple objective functions with optimization priorities are also supported: http://hackage.haskell.org/package/sbv-6.0/docs/Data-SBV.html#g:44 Objective values that assume their optimal values at infinity and epsilon are also supported, allowing the user to express arbitrary combinations of goals. Furthermore, soft-goals (i.e., those that can be violated with a user-specified penalty) are included as well. Such goals can be used to expressed "nice-to-have" constraints, for instance as they appear in classic scheduling problems. (Optimization is currently only supported by the z3-backend, and leverages the features of the z3 SMT solver. Please make sure you get a fresh copy of it from github .) A few basic examples: - Basic linear optimization over reals - Workshop product allocation - Allocating virtual-machines in data-centers This release also comes with a number of other changes/features, including support for user given tactics, mainly aimed for advanced users. See here for details. Bug reports, as always, are most welcome. -Levent. -------------- next part -------------- An HTML attachment was scrubbed... URL: From clintonmead at gmail.com Mon May 8 05:57:41 2017 From: clintonmead at gmail.com (Clinton Mead) Date: Mon, 8 May 2017 15:57:41 +1000 Subject: [Haskell-cafe] List instance of Alternative: why (++)? In-Reply-To: References: Message-ID: Where mappend, mplus and <|> and <> are defined, do they (and should they) always produce the same results? On Sun, May 7, 2017 at 5:23 PM, Jon Purdy wrote: > D’oh, that’s what I get for writing untested code in an email. > > Neutral doesn’t seem necessary since we have “null” in Foldable. I was > thinking more along these lines: > > instance (Alternative f, Foldable f) => Alternative (LeftBiased f) where > empty = LeftBiased empty > LeftBiased a <|> LeftBiased b = LeftBiased (if null a then b else a) > > Under the assumption that “null empty” always holds. I think using the > Alternative constraint for just “empty” makes sense because LeftBiased and > RightBiased should only differ from the wrapped type in the implementation > of (<|>), but it still seems a little iffy somehow. > > To make the wrapping slightly less painful, another good bikeshed colour > would be Pre/Post. (Dunno what you’d call “Unbiased” in that case, though.) > > On a related note, I recall there was some discussion a while back about > making a Monoid instance for Map where mappend is “unionWith mappend” > instead of the left-biased “union”. These wrappers could also be used for > that sort of thing, and it’d be nice to have a single standard for them > with all the different use cases fleshed out. > > On Sat, May 6, 2017 at 4:19 PM, MarLinn wrote: > >> >> On 2017-05-07 00:23, Jon Purdy wrote: >> >> I’ve wanted this before as well. Maybe we should throw a newtype at it? >> >> newtype LeftBiased a = LeftBiased [a] >> instance Alternative (LeftBiased a) where >> empty = [] >> [] <|> b = b >> a <|> _ = a >> >> newtype RightBiased a = RightBiased [a] >> instance Alternative (RightBiased a) where >> empty = [] >> a <|> [] = a >> _ <|> b = b >> >> You forgot the fun wrapping and unwrapping. But no matter. Let's >> generalize! >> >> class Neutral a where >> neutral :: a >> isNeutral :: a -> Bool >> >> instance Neutral a => Alternative (LeftBiased a) where >> empty = LeftBiased neutral >> (LeftBiased a) <|> (LeftBiased b) = LeftBiased $ if isNeutral a then b else a >> >> instance Neutral a => Alternative (RightBiased a) where >> empty = RightBiased neutral >> (RightBiased a) <|> (RightBiased b) = RightBiased $ if isNeutral b then a else b >> >> Why? >> >> type AllRight e a = LeftBiased (Either e a) >> type AnyRight e a = RightBiased (Either e a) >> >> instance Neutral a => Neutral (AllRight e a) where >> neutral = Right $ LeftBiased neutral >> isNeutral = fmap isRight >> >> instance Neutral e => Neutral (AnyRight e a) where >> neutral = Left $ RightBiased neutral >> isNeutral = fmap isLeft >> >> Is this a bit silly? Yes. My actual goal is to show that these concepts >> are bigger than they might appear, and how painful all those wrappers are. >> This is to advertise my language extension from my separate thread. And >> also because it's silly fun. Mostly that. >> >> >> newtype Unbiased a = Unbiased (Maybe a) >> instance (Monoid m) => Alternative (Unbiased m) where >> empty = Nothing >> Just a <|> Just b = Just (a <> b) >> _ <|> Just b = Just b >> Just a <|> _ = Just a >> _ <|> _ = Nothing >> >> Mh, that's just liftA2 (<>) a b <|> a <|> b in terms of the regular >> instance. Now that is easy to generalize – just don't use it for lists. >> Cheers, >> MarLinn >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. >> > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From P.Achten at cs.ru.nl Mon May 8 08:43:56 2017 From: P.Achten at cs.ru.nl (Peter Achten) Date: Mon, 8 May 2017 10:43:56 +0200 Subject: [Haskell-cafe] Deadline extension may 15: Trends in Functional Programming, 19-21 june 2017, University of Kent, Canterbury Message-ID: <17928eaf-e001-cd55-68b9-73e30fc9899f@cs.ru.nl> TFP 2017 EXTENSION: Deadline extension until Monday, 15 May (anywhere on earth). -------------------------------------------------------------------------------- We encourage anyone who wants to present their work at TFP in Canterbury, England this June to submit a 2-10 page abstract if time is too short to put together a full paper. ----------------------------- F I N A L C A L L F O R P A P E R S ----------------------------- ======== TFP 2017 =========== 18th Symposium on Trends in Functional Programming 19-21 June, 2017 University of Kent, Canterbury https://www.cs.kent.ac.uk/events/tfp17/index.html The symposium on Trends in Functional Programming (TFP) is an international forum for researchers with interests in all aspects of functional programming, taking a broad view of current and future trends in the area. It aspires to be a lively environment for presenting the latest research results, and other contributions (see below). Authors of draft papers will be invited to submit revised papers based on the feedback receive at the symposium. A post-symposium refereeing process will then select a subset of these articles for formal publication. TFP 2017 will be the main event of a pair of functional programming events. TFP 2017 will be accompanied by the International Workshop on Trends in Functional Programming in Education (TFPIE), which will take place on 22 June. The TFP symposium is the heir of the successful series of Scottish Functional Programming Workshops. Previous TFP symposia were held in * Edinburgh (Scotland) in 2003; * Munich (Germany) in 2004; * Tallinn (Estonia) in 2005; * Nottingham (UK) in 2006; * New York (USA) in 2007; * Nijmegen (The Netherlands) in 2008; * Komarno (Slovakia) in 2009; * Oklahoma (USA) in 2010; * Madrid (Spain) in 2011; * St. Andrews (UK) in 2012; * Provo (Utah, USA) in 2013; * Soesterberg (The Netherlands) in 2014; * Inria Sophia-Antipolis (France) in 2015; * and Maryland (USA) in 2016. For further general information about TFP please see the TFP homepage. (http://www.tifp.org/). == SCOPE == The symposium recognizes that new trends may arise through various routes. As part of the Symposium's focus on trends we therefore identify the following five article categories. High-quality articles are solicited in any of these categories: Research Articles: leading-edge, previously unpublished research work Position Articles: on what new trends should or should not be Project Articles: descriptions of recently started new projects Evaluation Articles: what lessons can be drawn from a finished project Overview Articles: summarizing work with respect to a trendy subject Articles must be original and not simultaneously submitted for publication to any other forum. They may consider any aspect of functional programming: theoretical, implementation-oriented, or experience-oriented. Applications of functional programming techniques to other languages are also within the scope of the symposium. Topics suitable for the symposium include, but are not limited to: Functional programming and multicore/manycore computing Functional programming in the cloud High performance functional computing Extra-functional (behavioural) properties of functional programs Dependently typed functional programming Validation and verification of functional programs Debugging and profiling for functional languages Functional programming in different application areas: security, mobility, telecommunications applications, embedded systems, global computing, grids, etc. Interoperability with imperative programming languages Novel memory management techniques Program analysis and transformation techniques Empirical performance studies Abstract/virtual machines and compilers for functional languages (Embedded) domain specific languages New implementation strategies Any new emerging trend in the functional programming area If you are in doubt on whether your article is within the scope of TFP, please contact the TFP 2017 program chairs, Scott Owens and Meng Wang. == BEST PAPER AWARDS == To reward excellent contributions, TFP awards a prize for the best paper accepted for the formal proceedings. TFP traditionally pays special attention to research students, acknowledging that students are almost by definition part of new subject trends. A student paper is one for which the authors state that the paper is mainly the work of students, the students are listed as first authors, and a student would present the paper. A prize for the best student paper is awarded each year. In both cases, it is the PC of TFP that awards the prize. In case the best paper happens to be a student paper, that paper will then receive both prizes. == PAPER SUBMISSIONS == Acceptance of articles for presentation at the symposium is based on a lightweight peer review process of extended abstracts (4 to 10 pages in length) or full papers (20 pages). The submission must clearly indicate which category it belongs to: research, position, project, evaluation, or overview paper. It should also indicate which authors are research students, and whether the main author(s) are students. A draft paper for which ALL authors are students will receive additional feedback by one of the PC members shortly after the symposium has taken place. We use EasyChair for the refereeing process. Papers must be submitted at: https://easychair.org/conferences/?conf=tfp17 Papers must be written in English, and written using the LNCS style. For more information about formatting please consult the Springer LNCS web site: http://www.springer.com/computer/lncs?SGWID=0-164-6-793341-0 == INVITED SPEAKERS == Conor McBride University of Strathclyde (UK) Cătălin Hriţcu INRIA Paris (FR) == IMPORTANT DATES == Submission of draft papers: ***15 May, 2017*** extension Notification: 12 May, 2017 Registration: 11 June, 2017 TFP Symposium: 19-21 June, 2017 Student papers feedback: 29 June, 2017 Submission for formal review: 2 August, 2017 Notification of acceptance: 3 November, 2017 Camera ready paper: 2 December, 2017 == PROGRAM COMMITTEE == Co-Chairs Meng Wang University of Kent (UK) Scott Owens University of Kent (UK) PC Jeremy Yallop University of Cambridge (UK) Nicolas Wu University of Bristol (UK) Laura Castro University of A Coruña (ES) Gabriel Scherer Northeastern University (US) Edwin Brady University of St Andrews (UK) Janis Voigtländer Radboud University Nijmegen (NL) Peter Achten Radboud University Nijmegen (NL) Tom Schrijvers KU Leuven (BE) Matthew Fluet Rochester Institute of Technology (US) Mauro Jaskelioff CIFASIS/Universidad Nacional de Rosario (AG) Patricia Johann Appalachian State University (US) Bruno Oliveira The University of Hong Kong (HK) Rita Loogen Philipps-Universität Marburg (GE) David Van Horn University of Marylan (US) Soichiro Hidaka Hosei University (JP) Michał Pałka Chalmers University of Technology (SE) Sandrine Blazy University of Rennes 1 - IRISA (FR) From dct25-561bs at mythic-beasts.com Mon May 8 16:02:52 2017 From: dct25-561bs at mythic-beasts.com (David Turner) Date: Mon, 8 May 2017 17:02:52 +0100 Subject: [Haskell-cafe] Bug in random shuffle algorithm Message-ID: https://wiki.haskell.org/Random_shuffle says: Here's a variation using the MonadRandom package: import Control.Monad import Control.Monad.ST import Control.Monad.Random import System.Random import Data.Array.ST import GHC.Arr shuffle :: RandomGen g => [a] -> Rand g [a] shuffle xs = do let l = length xs rands <- take l `fmap` getRandomRs (0, l-1) let ar = runSTArray $ do ar <- thawSTArray $ listArray (0, l-1) xs forM_ (zip [0..(l-1)] rands) $ \(i, j) -> do vi <- readSTArray ar i vj <- readSTArray ar j writeSTArray ar j vi writeSTArray ar i vj return ar return (elems ar) But this doesn't yield a uniformly-chosen random permutation of its input, because at the i'th step the first `i` elements are not fixed as they are in the other algorithms on that page. Cheers, David -------------- next part -------------- An HTML attachment was scrubbed... URL: From monkleyon at gmail.com Mon May 8 20:16:16 2017 From: monkleyon at gmail.com (MarLinn) Date: Mon, 8 May 2017 22:16:16 +0200 Subject: [Haskell-cafe] Language extension proposal: aspects In-Reply-To: References: <670697a8-e2ea-3af8-d8e0-862ffc489562@gmail.com> Message-ID: <74f7ce71-72ed-e801-7133-4f75c4d63b1b@gmail.com> An HTML attachment was scrubbed... URL: From monkleyon at gmail.com Mon May 8 20:41:32 2017 From: monkleyon at gmail.com (MarLinn) Date: Mon, 8 May 2017 22:41:32 +0200 Subject: [Haskell-cafe] Language extension proposal: aspects In-Reply-To: References: <670697a8-e2ea-3af8-d8e0-862ffc489562@gmail.com> Message-ID: <8c6db175-0466-48b5-42ea-c945a1b7353e@gmail.com> On 2017-05-07 11:21, Dmitry Olshansky wrote: > But in this case I'm afraid that we end-up with the same noise as for > the newtype. But instead of construct to and deconstruct from newtype > we will have to define aspects on type level for caller and define > constraint for function. Usually type-level syntax is more complicated... On the one hand, I get what you're saying. I'm not sure I'm totally convinced my idea is bad because of it, but I'll ponder that. On the other hand… in a way, we're working with two programming languages, a value level one and a type level one. And you're right that the type level programing language can be quite obtuse, even without my proposed additions. But I don't directly see that as an argument against my proposal. It's more of an argument to straighten out our type level language. I mean what is our type level language? It's basically a logic programming language that guides a constraint solver. We state facts and relationships, and we get an "ok" or errors and as "side effects" we sometimes get dictionaries. Now look at Prolog and how simple it is. Our language is more specialized, so we have more specialized operators. But that alone would only make the language more complex, not necessarily more complicated. In an ideal world I would also just be able to use existing tools of our type level language to implement my additions. Right now I can't, so something is amiss. To be honest I don't have any idea how to fix this. And as long as we don't, your argument against my proposal is indeed valid through this indirection. But I'm not happy that it is… Cheers, MarLinn From tanuki at gmail.com Mon May 8 22:51:05 2017 From: tanuki at gmail.com (Theodore Lief Gannon) Date: Mon, 8 May 2017 15:51:05 -0700 Subject: [Haskell-cafe] Language extension proposal: aspects In-Reply-To: <74f7ce71-72ed-e801-7133-4f75c4d63b1b@gmail.com> References: <670697a8-e2ea-3af8-d8e0-862ffc489562@gmail.com> <74f7ce71-72ed-e801-7133-4f75c4d63b1b@gmail.com> Message-ID: On Mon, May 8, 2017 at 1:16 PM, MarLinn wrote: > On 2017-05-07 05:19, Theodore Lief Gannon wrote: > > To avoid surprises, they shouldn't propagate -- when foldMap invokes even, > it sees the default Monoid instance for Bool (i.e. none). > > That sounds like a gateway to inconsistency. I think the solution is that > adding an aspect to, say, an Int would not apply that aspects to all Int's, > but only to the ones unifying with the annotated one. > Hmm... this might work? As long as you can handle the situation where a higher-order function depends on one instance, but a function passed to it depends on another. (Consider Maybe, which has at least four legal Monoid instances, one of which is default!) -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.jones at uncannyworks.com Tue May 9 03:31:17 2017 From: brian.jones at uncannyworks.com (Brian Jones) Date: Tue, 9 May 2017 12:31:17 +0900 Subject: [Haskell-cafe] Parse stream using an external template for rules? Message-ID: I'm not completely sure what I am looking for so I figured I'd ask the community. I have a project which reads data from a telnet stream (I wrote a pipes-network[1] library to handle this), however, rather than hard code the parsing rules with something like attoparsec (as I have done in my example) I'd like to define a template language which reads in a file with the template definitions that describes what to parse instead and use that inside the parser step. What tools and approaches would you recommend in this case? Or alternatively, a better solution? Thanks, Brian [1] https://github.com/alasconnect/pipes-telnet From ietf-dane at dukhovni.org Tue May 9 05:46:52 2017 From: ietf-dane at dukhovni.org (Viktor Dukhovni) Date: Tue, 9 May 2017 01:46:52 -0400 Subject: [Haskell-cafe] Bug in random shuffle algorithm In-Reply-To: References: Message-ID: > On May 8, 2017, at 12:02 PM, David Turner wrote: > > But this doesn't yield a uniformly-chosen random permutation of its input, because at the i'th step the first `i` elements are not fixed as they are in the other algorithms on that page. Channeling Samuel Dukhovni, who provided a patch for the same bug in older versions of Postfix a few years back, his suggested patch is: shuffle :: RandomGen g => [a] -> Rand g [a] shuffle xs = do let l = length xs - rands <- take l `fmap` getRandomRs (0, l-1) + rands <- forM [0..(l-1)] (\i -> getRandomR (i, l-1)) let ar = runSTArray $ do ar <- thawSTArray $ listArray (0, l-1) xs forM_ (zip [0..(l-1)] rands) $ \(i, j) -> do vi <- readSTArray ar i vj <- readSTArray ar j writeSTArray ar j vi writeSTArray ar i vj return ar return (elems ar) Perhaps someone can forward this along to the package maintainer. Also as an optimization, the `rands` list should be made one element shorter, and likewise the `zip [0..(l-1)]` should become `zip [0..(l-2)]`. The reason is of course that by the time we only have one final element left there's nothing left to permute. -- Viktor. P.S. The corresponding new Postfix code can be found at https://github.com/vdukhovni/postfix/blob/master/postfix/src/dns/dns_rr.c#L305 /* * Shuffle resource records. Every element has an equal chance of landing * in slot 0. After that every remaining element has an equal chance of * landing in slot 1, ... This is exactly n! states for n! permutations. */ for (i = 0; i < len - 1; i++) { r = i + (myrand() % (len - i)); /* Victor&Son */ rr = rr_array[i]; rr_array[i] = rr_array[r]; rr_array[r] = rr; } From ketil at malde.org Tue May 9 07:29:37 2017 From: ketil at malde.org (Ketil Malde) Date: Tue, 09 May 2017 09:29:37 +0200 Subject: [Haskell-cafe] Error using Judy arrays (was: Re: [Biohaskell] hash map/associative structure) In-Reply-To: References: <87fugq2vcm.fsf@malde.org> <68C8DAA5-42E3-4DAF-9687-94E9F48F5434@gmail.com> <87y3udx7hn.fsf@malde.org> Message-ID: <874lwuwkri.fsf@malde.org> On 2017-05-04 12:14 (+0200), Michał J Gajda wrote: > Interesting. Do You have an error report filed anywhere to peruse? Well, I wrote the below. In the mean time, I've tried replacing "insertWith" with a manual lookup and update. This changed the cases where the segfaults happen, but didn't eliminate them. And I tried using the safe freeze function, to no avail. And I implemented some of the functionality using a Vector, which gives correct results (but without reimplementing a real hashtable, it can only be used for the histogram collection, not k-mer counting, since with large k that requires full 64-bit indexes into the vector) I've also run on several different computers, so I don't think it's a hardware error. -k ---------------------------------------- So: I have a program that indexes k-mers (fixed-size words) as Word64's, storing the different ones along with their counts in a Judy array, and at the end, writing to a file. So an associative map mapping k-word -> count. Then, the second stage re-reads this file, and builds a histogram, tallying how often each count occurs. let's call this count -> frequency For some time, this just seemed to work. But then I implemented an expectation-maximization algorithm to model the frequency distributions, and that failed to terminate in some cases. Going back, I found the following histogram to cause the trouble: ==> SRR901891_1.32.hist <== 865 809 866 775 867 757 868 781 869 725 870 778 871 795 872 774 873 771 48036128 2017612633061982208 Notice that last value? Apparently, there are 2.018e18 different k-mers with a frequency of 48036128. This is clearly not right. Notice also that the latter number is 0x01c000...000. Does this carry any special meaning? One possibility is of course some garbage in the k-mer count index, but I also have a dump command that prints the contents as text. I can find nothing wrong with that, and the highest count k-mers look like this: % sort -nr -k2 *dump* | head tgggggtccagccatggagaagagtttagaca 1670602 gggggtccagccatggagaagagtttagacac 1653146 gtctaaactcttctccatggctggacccccaa 1638158 gaatattatttgggggtccagccatggagaag 1567591 ggaatattatttgggggtccagccatggagaa 1539378 actagtgcttaggaaatctattggaggcagaa 1532596 gcttctgcctccaatagatttcctaagcacta 1531091 aggaatattatttgggggtccagccatggaga 1528806 ctagtgcttaggaaatctattggaggcagaag 1527682 aaaggaatattatttgggggtccagccatgga 1518392 One thing to look into is how the histogram is built. I have wrapped this in a function (mk_judy, code below) that returns a struct of operations, called FreqCount. mk_judy takes as an argument the number of bits to use in the index - but this isn't really used for anything (JudyL is JudyL). Yet, when I changed this parameter from 16 to 32, the last line changed to: 17180896 2017612633061982208 And with 64: 37271776 2017612633061982208 The latter number is always the same, the former ends with 0x8e0, but appears to vary in the most significant bits. Everything else is the same in the histograms, I did a diff on the outputs. -- Code ---------------------------------------- mk_judy :: Int -> IO FreqCount mk_judy l = do j <- J.new :: IO (J.JudyL Int) let ac k = k `seq` J.insertWith (+) k 1 j gc k = k `seq` fromMaybe 0 `fmap` J.lookup k j sc k v = J.insert k v j es = J.unsafeFreeze j >>= J.elems ks = J.unsafeFreeze j >>= J.keys as = J.unsafeFreeze j >>= J.toList return $ FreqCount { key_bits = l , add_count = ac, get_count = gc, set_count = sc , keys = ks, counts = es, assocs = as } -- Code ---------------------------------------- If we're sure there is nothing wrong with the Judy library, the only other thing I can think of is the unsafeFreeze. I'm pretty sure I don't modify the Judy array after accessing it through the "frozen" functions - but could it e.g. be the case that j is frozen with some operations still unevaluated? I tried adding "j `seq`" before unsafeFreeze, and got: 33769696 2017612633061982208 Again, 0x...8e0 and the usual 0x01c0... Anyway, that's where it stands at the moment. I'm not sure what to do, it does worry me that this counting seems to fail on occasion. Note also that the histogram gets truncated (always at the same place, after 873), and it should really go up to 1.5 million. ---------------------------------------- -- If I haven't seen further, it is by standing in the footprints of giants From robert at gonimo.com Tue May 9 08:13:17 2017 From: robert at gonimo.com (Robert Klotzner) Date: Tue, 9 May 2017 10:13:17 +0200 Subject: [Haskell-cafe] [ANN] gonimo web-based baby monitor has launched! Message-ID: <7037af93-32bf-c7bd-2f15-4129f19485d5@gonimo.com> Hi to all Haskell-er parents out there! Always hated that your baby monitor is the only thing left in your household not coded in Haskell? Well, don't worry no more! Gonimo is here! Visit gonimo.com and have a baby monitor coded in Haskell! All you need is a recent web-browser (Chrome works best) on any non iOS platform! :-) Source code on github ! Hope you like it! Feedback, very welcome! Uh and we have a facebook page too! facebook.com/mygonimo ! If you like our baby monitor consider a like or even share - it is pretty hard with no money to reach potential users, so this would really be awesome! Best regards, Robert -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 488 bytes Desc: OpenPGP digital signature URL: From michael at snoyman.com Tue May 9 08:53:34 2017 From: michael at snoyman.com (Michael Snoyman) Date: Tue, 09 May 2017 08:53:34 +0000 Subject: [Haskell-cafe] [ANN] gonimo web-based baby monitor has launched! In-Reply-To: <7037af93-32bf-c7bd-2f15-4129f19485d5@gonimo.com> References: <7037af93-32bf-c7bd-2f15-4129f19485d5@gonimo.com> Message-ID: The timing on this email was great, and the app worked perfectly. Thank you for sharing! On Tue, May 9, 2017, 11:15 AM Robert Klotzner wrote: > Hi to all Haskell-er parents out there! > > Always hated that your baby monitor is the only thing left in your > household not coded in Haskell? > > Well, don't worry no more! Gonimo is here! Visit gonimo.com and have a > baby monitor coded in Haskell! All you need is a recent web-browser (Chrome > works best) on any non iOS platform! :-) > > Source code on github ! > > Hope you like it! Feedback, very welcome! > > > Uh and we have a facebook page too! facebook.com/mygonimo ! If you like > our baby monitor consider a like or even share - it is pretty hard with no > money to reach potential users, so this would really be awesome! > > > Best regards, > > > Robert > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jo at durchholz.org Tue May 9 10:59:06 2017 From: jo at durchholz.org (Joachim Durchholz) Date: Tue, 9 May 2017 12:59:06 +0200 Subject: [Haskell-cafe] =?utf-8?q?=5Bperl_=23129843=5D_=5BLTA=5D_Indexing_?= =?utf-8?q?on_a_Str_throws_generic_=E2=80=9Cout_of_range=E2=80=9D_message_?= =?utf-8?b?d2hpY2ggaXMgbGVzcyB0aGFuIGF3ZXNvbWUgKOKAnGhlbGxv4oCdWzJdKQ==?= In-Reply-To: References: Message-ID: <39a47bb8-a37f-50e5-4cdc-7b1719db18bb@durchholz.org> Am 08.05.2017 um 23:00 schrieb Brandon Allbery: > > On Mon, May 8, 2017 at 4:49 PM, Joachim Durchholz > wrote: > > If the mental model for Perl6 strings is "array of characters" though > > Perl has never had that mental model, is my point. Right, I should have written "is supposed to evolve to" instead of "is". Array of characters may be a useful abstraction to have in Perl6, or not (see below). > It's generally > imported by folks who come from languages where strings *are* "arrays of > characters" --- and where that model has a strong tendency to cause > problems. (See Python 3's struggles with Unicode as an example. And > C/C++, well, don't even get me started. Some of these struggles originate from equating bytes with characters. Since Perl6 is more or less a clean slate, it can avoid these. Other struggles originate from the structure of Unicode: it defines multiple levels of sequences, each useful for different tasks: - code points - graphemes - characters (various normalizations exist) - word parts (for line breaking) - words - sentences - paragraphs and possible a few more. Ideally, developers will be able to use the same API structure at each level, maybe with the exception of the grapeme level where Perl6 has its native representation (the better the API, the less of such implementation details is visible and relevant to the programmer). > Bytes stopped being the basis of > characters even *before* Unicode. C and C++ are still struggling to > understand that. I think you're being unfair to them. The issues are actually well-understood in the C++ arena, as demonstrated by the ICU library. It's just that language evolution is constrained by legacy, plus possibly short-sighed decisions by compiler makers. Also, C++ (by necessity) evolves slower than Unicode. Under these conditions, Unicode support in a library is actually preferrable to anything inside the language, it's enough if the language can interoperate with the library. From lysxia at gmail.com Tue May 9 13:38:07 2017 From: lysxia at gmail.com (Li-yao Xia) Date: Tue, 9 May 2017 09:38:07 -0400 Subject: [Haskell-cafe] Bug in random shuffle algorithm In-Reply-To: References: Message-ID: Hello, Thank you David for reporting this and thank you Viktor for the fix. I edited the wiki. Li-yao On 05/09/2017 01:46 AM, Viktor Dukhovni wrote: >> On May 8, 2017, at 12:02 PM, David Turner wrote: >> >> But this doesn't yield a uniformly-chosen random permutation of its input, because at the i'th step the first `i` elements are not fixed as they are in the other algorithms on that page. > Channeling Samuel Dukhovni, who provided a patch for the same bug in > older versions of Postfix a few years back, his suggested patch is: > > shuffle :: RandomGen g => [a] -> Rand g [a] > shuffle xs = do > let l = length xs > - rands <- take l `fmap` getRandomRs (0, l-1) > + rands <- forM [0..(l-1)] (\i -> getRandomR (i, l-1)) > let ar = runSTArray $ do > ar <- thawSTArray $ listArray (0, l-1) xs > forM_ (zip [0..(l-1)] rands) $ \(i, j) -> do > vi <- readSTArray ar i > vj <- readSTArray ar j > writeSTArray ar j vi > writeSTArray ar i vj > return ar > return (elems ar) > > Perhaps someone can forward this along to the package maintainer. > > Also as an optimization, the `rands` list should be made one element > shorter, and likewise the `zip [0..(l-1)]` should become `zip [0..(l-2)]`. > The reason is of course that by the time we only have one final element > left there's nothing left to permute. > From S.J.Thompson at kent.ac.uk Tue May 9 18:54:40 2017 From: S.J.Thompson at kent.ac.uk (Simon Thompson) Date: Tue, 9 May 2017 19:54:40 +0100 Subject: [Haskell-cafe] TFPIE - Trends in Functional Programming in Education 2017 - Deadline extended to 17 May Message-ID: <1D3E4190-0DAD-45FA-8054-A897AAE0CF46@kent.ac.uk> After a number of requests, we have extended the deadline for TFPIE 2017 to 17 May. Please consider submitting if you’re interested in hearing about how to get the functional message shared more widely. A particular topic of this year's TFPIE will be MOOCs and other online learning and, as well as a session on this, we're delighted to announce that Heather Miller of EFPL and Northeastern University will be giving a keynote on this topic. Heather works on and around the Scala programming language and is Executive Director of the Scala Center. We'll also have Yann Regis-Gianas and Benjamin Canou from the OCaml MOOC team, Jeremy Singer (Haskell), and Simon Thompson (Erlang). TFPIE 2017 - DEADLINE EXTENDED TO 17 MAY Trends in Functional Programming in Education, 2017 https://www.cs.kent.ac.uk/people/staff/sjt/TFPIE2017/ The sixth workshop on Trends in Functional Programming in Education, 2017, which is to be held on the Canterbury campus of the University of Kent on Thursday, 22 June, following the 2017 TFP meeting on 19–21 June. TFPIE workshops have previously been held in St Andrews, Scotland (2012), Provo Utah, USA (2013), Soesterberg, The Netherlands (2014), and Sophia-Antipolis, France (2015), College Park, USA (2016). The goal of TFPIE is to gather researchers, teachers and professionals that use, or are interested in the use of, functional programming in education. TFPIE aims to be a venue where novel ideas, classroom-tested ideas and work-in-progress on the use of functional programming in education are discussed. The one-day workshop will foster a spirit of open discussion by having a review process for publication after the workshop. The program chair of TFPIE 2017 will screen submissions to ensure that all presentations are within scope and are of interest to participants. After the workshop, presenters will be invited to submit revised versions of their articles for publication in the journal Electronic Proceedings in Theoretical Computer Science (EPTCS). Final call for papers TFPIE 2017 welcomes submissions describing techniques used in the classroom, tools used in and/or developed for the classroom and any creative use of functional programming (FP) to aid education in or outside Computer Science. Topics of interest include, but are not limited to: - FP and beginning CS students - FP and Computational Thinking - FP and Artificial Intelligence - FP in Robotics - FP and Music - Advanced FP for undergraduates - FP in graduate education - Engaging students in research using FP - FP in Programming Languages - FP in the high school curriculum - FP as a stepping stone to other CS topics - FP and Philosophy - The pedagogy of teaching FP - FP and e-learning: MOOCs, automated assessment etc. - Best Lectures – more details below In addition to papers, we are requesting best lecture presentations. What’s your best lecture topic in an FP related course? Do you have a fun way to present FP concepts to novices or perhaps an especially interesting presentation of a difficult topic? In either case, please consider sharing it. Best lecture topics will be selected for presentation based on a short abstract describing the lecture and its interest to TFPIE attendees. Submission Potential presenters are invited to submit an extended abstract (4-6 pages) or a draft paper (up to 16 pages) in EPTCS style. The authors of accepted presentations will have their preprints and their slides made available on the workshop's website. Papers and abstracts can be submitted via easychair at the following link: https://easychair.org/conferences/?conf=tfpie2017 After the workshop, presenters will be invited to submit (a revised version of) their article for review. The PC will select the best articles for publication in the journal Electronic Proceedings in Theoretical Computer Science (EPTCS). Articles rejected for presentation and extended abstracts will not be formally reviewed by the PC. Programme committee Dr Laura Castro, University of A Coruña Prof Ralf Lämmel, University of Koblenz-Landau Dr Elena Machkasova, University of Minnesota, Morris Prof Michel Mauny, Inria, Paris Dr Jeremy Singer, University of Glasgow Prof Simon Thompson, University of Kent (chair) Important dates Submissions of draft papers: 17 May, 2017 Notification: 22 May, 2017 Registration: 11 June, 2017 Workshop: 22 June 2017 Submission for formal review: 18 August, 2017 Notification of acceptance: 6 October, 2017 Camera ready paper: 3 November, 2017 Simon Thompson | Professor of Logic and Computation School of Computing | University of Kent | Canterbury, CT2 7NF, UK s.j.thompson at kent.ac.uk | M +44 7986 085754 | W www.cs.kent.ac.uk/~sjt From olf at aatal-apotheke.de Tue May 9 19:33:18 2017 From: olf at aatal-apotheke.de (Olaf Klinke) Date: Tue, 9 May 2017 21:33:18 +0200 Subject: [Haskell-cafe] [Biohaskell] Error using Judy arrays (was: Re: hash map/associative structure) In-Reply-To: <874lwuwkri.fsf@malde.org> References: <87fugq2vcm.fsf@malde.org> <68C8DAA5-42E3-4DAF-9687-94E9F48F5434@gmail.com> <87y3udx7hn.fsf@malde.org> <874lwuwkri.fsf@malde.org> Message-ID: <5822E897-F078-40E2-A4D6-CEB71DAFABCF@aatal-apotheke.de> Ketil, Given that the dump looks fine, my gut feeling is that indeed the histogram function operates on partially evaluated data and somehow the memory is corrupted. Can you write a Deepseq instance for your Judy array? After all, you could dump to a [(String,Int)] instead of an IO handle and re-parse the data. I guess that forcing the k-mer itself to be fully evaluated does no good (it's a Word64, anyways?). You'd need to make sure the insertWith (+) operation is fully evaluated. Finally, can you rule out a normal overflow? I had sequencing runs where fastx_nucleotide_distribution_graph.sh simply overflowed the Int counter. Using Haskell's Integer produced correct results. Yet the thing with the bit number influencing the outcome sounds very much like data corruption. Olaf > Am 09.05.2017 um 09:29 schrieb Ketil Malde : > > > On 2017-05-04 12:14 (+0200), Michał J Gajda wrote: > >> Interesting. Do You have an error report filed anywhere to peruse? > > Well, I wrote the below. In the mean time, I've tried replacing > "insertWith" with a manual lookup and update. This changed the cases > where the segfaults happen, but didn't eliminate them. > > And I tried using the safe freeze function, to no avail. > > And I implemented some of the functionality using a Vector, which gives > correct results (but without reimplementing a real hashtable, it can > only be used for the histogram collection, not k-mer counting, since > with large k that requires full 64-bit indexes into the vector) > > I've also run on several different computers, so I don't think it's a > hardware error. > > -k > > ---------------------------------------- > So: I have a program that indexes k-mers (fixed-size words) as Word64's, > storing the different ones along with their counts in a Judy array, and > at the end, writing to a file. So an associative map mapping > k-word -> count. > > Then, the second stage re-reads this file, and builds a histogram, > tallying how often each count occurs. let's call this count -> frequency > > For some time, this just seemed to work. But then I implemented an > expectation-maximization algorithm to model the frequency distributions, > and that failed to terminate in some cases. Going back, I found the > following histogram to cause the trouble: > > ==> SRR901891_1.32.hist <== > 865 809 > 866 775 > 867 757 > 868 781 > 869 725 > 870 778 > 871 795 > 872 774 > 873 771 > 48036128 2017612633061982208 > > Notice that last value? Apparently, there are 2.018e18 different > k-mers with a frequency of 48036128. This is clearly not right. > > Notice also that the latter number is 0x01c000...000. Does this carry > any special meaning? > > One possibility is of course some garbage in the k-mer count index, but > I also have a dump command that prints the contents as text. I can find > nothing wrong with that, and the highest count k-mers look like this: > > % sort -nr -k2 *dump* | head > tgggggtccagccatggagaagagtttagaca 1670602 > gggggtccagccatggagaagagtttagacac 1653146 > gtctaaactcttctccatggctggacccccaa 1638158 > gaatattatttgggggtccagccatggagaag 1567591 > ggaatattatttgggggtccagccatggagaa 1539378 > actagtgcttaggaaatctattggaggcagaa 1532596 > gcttctgcctccaatagatttcctaagcacta 1531091 > aggaatattatttgggggtccagccatggaga 1528806 > ctagtgcttaggaaatctattggaggcagaag 1527682 > aaaggaatattatttgggggtccagccatgga 1518392 > > One thing to look into is how the histogram is built. I have wrapped > this in a function (mk_judy, code below) that returns a struct of > operations, called FreqCount. mk_judy takes as an argument the number > of bits to use in the index - but this isn't really used for anything > (JudyL is JudyL). Yet, when I changed this parameter from 16 to 32, the > last line changed to: > > 17180896 2017612633061982208 > > And with 64: > > 37271776 2017612633061982208 > > The latter number is always the same, the former ends with 0x8e0, but > appears to vary in the most significant bits. > > Everything else is the same in the histograms, I did a diff on the > outputs. > > -- Code ---------------------------------------- > mk_judy :: Int -> IO FreqCount > mk_judy l = do > j <- J.new :: IO (J.JudyL Int) > let ac k = k `seq` J.insertWith (+) k 1 j > gc k = k `seq` fromMaybe 0 `fmap` J.lookup k j > sc k v = J.insert k v j > es = J.unsafeFreeze j >>= J.elems > ks = J.unsafeFreeze j >>= J.keys > as = J.unsafeFreeze j >>= J.toList > return $ FreqCount { key_bits = l > , add_count = ac, get_count = gc, set_count = sc > , keys = ks, counts = es, assocs = as > } > -- Code ---------------------------------------- > > If we're sure there is nothing wrong with the Judy library, the only > other thing I can think of is the unsafeFreeze. I'm pretty sure I don't > modify the Judy array after accessing it through the "frozen" functions > - but could it e.g. be the case that j is frozen with some operations > still unevaluated? I tried adding "j `seq`" before unsafeFreeze, and > got: > > 33769696 2017612633061982208 > > Again, 0x...8e0 and the usual 0x01c0... > > Anyway, that's where it stands at the moment. I'm not sure what to do, > it does worry me that this counting seems to fail on occasion. Note > also that the histogram gets truncated (always at the same place, after > 873), and it should really go up to 1.5 million. > ---------------------------------------- > > -- > If I haven't seen further, it is by standing in the footprints of giants > _______________________________________________ > Biohaskell mailing list > Biohaskell at biohaskell.org > http://biohaskell.org/cgi-bin/mailman/listinfo/biohaskell From gershomb at gmail.com Wed May 10 04:03:36 2017 From: gershomb at gmail.com (Gershom B) Date: Wed, 10 May 2017 00:03:36 -0400 Subject: [Haskell-cafe] Announce: Haskell Platform 8.0.2-a builds for Windows 10 Creators Update Message-ID: As many people know, the recent Windows 10 Creators Update broke the latest GHC 8.0.2 release. [1] We're happy to announce that there are now new 8.0.2-a builds on the Haskell Platform website that include the patch prepared by GHC HQ, and the hashes have been updated appropriately as well: https://www.haskell.org/platform/windows.html Note that this is not a new HP release in any official sense, nor are these new HP builds. These are the existing installers with the replacement of one file. Accordingly, they have new file names and hashes. However, all else remains the same. Similarly, no builds for other platforms have been updated. If you are not using Windows 10, this doesn't affect you in any way. And if you are, you probably already ran into this. Apologies for about a week of tardiness in getting this out, which is entirely due to my frazzledness. Happy Haskell Hacking all, Gershom [1] https://mail.haskell.org/pipermail/ghc-devs/2017-April/014131.html From moritz.angermann at gmail.com Wed May 10 05:43:12 2017 From: moritz.angermann at gmail.com (Moritz Angermann) Date: Wed, 10 May 2017 13:43:12 +0800 Subject: [Haskell-cafe] GHC cross compilation survey results In-Reply-To: References: Message-ID: <4431C846-86DE-40C6-8FDB-20BF79ACE4A0@gmail.com> Dear friends, 20 days ago, together with obsidian.systems, we asked about cross compilation with GHC. A follow up with the result has been posted yesterday[1]. I’ll hope we can improve on many fronts and make building a cross compiling GHC as simple as ./configure --target=... --prefix=... [--disable-large-address-space] with GHC 8.4. I also plan on extending documentation on cross compiling, and maybe even provide pre-built cross compiles. I’ll plan to publish a few more posts regarding cross compiling in general and cross compiling with ghc specifically over the next few month at https://medium.com/@zw3rk. If you would like some more specific details of the survey, please feel free to contact me! Cheers, Moritz [1]: https://medium.com/@zw3rk/cross-compilation-survey-results-3988ad1b677b PS: I am building cross compilers for arm/raspberry pi, armv7/android, aarch64/android, aarch64/iOS, x86_64/iOS, all with limited* TH support as well as x86_64/macOS on a daily basis, and hope that this will ensure to a certain degree that master won’t break the cross compilers. *: without File IO (except for embedFile), and without Process IO. > On Apr 20, 2017, at 6:15 PM, Moritz Angermann wrote: > > Dear friends, > > as some of you might have noticed, together with > obsidian.systems, I’m trying to make cross compiling > GHC a bit easier. To that extend, I’d like to invite > you to fill out a short survey[1], so we understand > the needs of the community better. > > Please follow the attached link and fill out the > survey! > > Cheers, > Moritz > > [1]: https://medium.com/@zw3rk/hello-world-a-cross-compilation-survey-890cb95029d7 > > _______________________________________________ > ghc-devs mailing list > ghc-devs at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs From jkarni at gmail.com Wed May 10 09:10:32 2017 From: jkarni at gmail.com (Julian K. Arni) Date: Wed, 10 May 2017 11:10:32 +0200 Subject: [Haskell-cafe] Looking for (possibly temporary) maintainers Message-ID: <20170510091032.sechwovg52gz2tm2@Tal> Hi cafe! I'm going to be away from the internet from late May till early September, so I'm trying to ensure that all my packages have someone who could be responsible for them in the meantime. Minimally, this would involve reviewing new PRs and making releases with them, but you'd be free to take on a more active role too. If you want to continue being a maintainer after that, you'd be very welcome, but I do intend to help. Most of the packages already have other maintainers, but these don't: - bookkeeper (https://github.com/turingjump/bookkeeper) - extensible records library - verdict (https://github.com/jkarni/verdict) - refinement-type-like opaque types - servant-quickcheck (https://github.com/haskell-servant/servant-quickcheck) - quickcheck properties of entire APIs If you're interested, send me an email! Thanks, Julian Arni -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 455 bytes Desc: not available URL: From dmwit at galois.com Wed May 10 20:57:45 2017 From: dmwit at galois.com (Daniel Wagner) Date: Wed, 10 May 2017 13:57:45 -0700 Subject: [Haskell-cafe] Galois is hiring Message-ID: <1494449802-sup-109@teff> Here's our official announcement: > Galois is hiring! We're looking for researchers, principal investigators, software engineers, and project leads, including those with expertise in functional programming, formal methods, machine learning, embedded systems, computer security, or networking. We have offices in Arlington VA, Dayton OH, and Portland OR with positions available at all locations. For more info or to submit your resume, please see our website: http://galois.com/careers . Here's a few things I like about Galois [1]: * Deep technical problems. I've been involved in projects to develop a prototype voting system that gives cryptographic guarantees of privacy and correctness; to get a line of mobile phones' crypto subsystems certified; to build a tool for doing asynchronous hardware design; and to obfuscate programs in a cryptographically strong way. Every day in the break room I hear about projects my coworkers are in that are as exciting or more in terms of technical depth. * Flexibility. For example, I like variety, so I've joined up with several projects even in my short stay here, working for a few months on each; but other people like stability and prefer working full-time on a single project for long periods, and both modes are well-supported. You also get quite a lot of say over what projects you'll be working on; what you'll be doing on a given project; what technologies are most appropriate for that project's goals (I've used Haskell in some way in almost every project so far... I might be biased here); even where you get your work done on any given day (Need to work from home because there's ice on the roads, or because the cable guy said they'd be there "somewhere between 10 and midnight", or just because you want to head to a coffee shop for the ambience for the day? No problem!). * Training. Everybody here is a world-class expert, and I feel like I've learned a ton just by overhearing lunch conversations. The company also goes out of its way to support structured training. I was a complete crypto noob prior to joining, but they let me spend company time on a Coursera course so that I can at least see the blood after I've shot my own foot. Each year I've been here, everyone has also been given a week for "innovation time" that need not be spent on anything directly funded from outside; many folks spend this time getting acquainted with a new technology (or inventing one!). * Location. Portland is a medium-sized city -- just large enough to have one of everything. The weather goes a little below freezing for a few days each year and a little above body temperature for a few days each year -- which is a small price to pay for the temperate weather we get the rest of the time. Walking distance from the building we're in covers a lot of ground. If those things sound exciting to you, check out our openings at http://galois.com/careers. ~d [1] Cross-posted from reddit; apologies if this looks familiar! We're still actively looking for talented folks. https://www.reddit.com/r/haskell/comments/5r3vhz/galois_is_hiring/ From alpmestan at gmail.com Thu May 11 00:43:45 2017 From: alpmestan at gmail.com (Alp Mestanogullari) Date: Thu, 11 May 2017 02:43:45 +0200 Subject: [Haskell-cafe] Constraining constraints In-Reply-To: References: Message-ID: This might help? https://hackage.haskell.org/package/constraints-0.9.1/docs/Data-Constraint.html#t::-45- Le 7 mai 2017 06:21, "Clinton Mead" a écrit : > I posted the following on stackoverflow > , > but it hasn't got too much attention so I thought I'd ask here: > > I can write the following: > > {-# LANGUAGE RankNTypes #-}{-# LANGUAGE FlexibleInstances #-}{-# LANGUAGE UndecidableInstances #-}{-# LANGUAGE ConstraintKinds #-} > > f :: Integral a => (forall b. Num b => b) -> a > f = id > > And all is good. Presumably GHC can derive Integral from Num so all is > well. > > I can be a bit tricker, yet I'm still fine: > > class Integral x => MyIntegral xinstance Integral x => MyIntegral x > class Num x => MyNum xinstance Num x => MyNum x > > f' :: MyIntegral a => (forall b. MyNum b => b) -> a > f' = id > > So lets say I want to generalise this, like so: > > g :: c2 a => (forall b. c1 b => b) -> a > g = id > > Now obviously this will spit the dummy, because GHC can not derive c2 > from c1, as c2 is not constrained. > > What do I need to add to the type signature of g to say that "you can > derive c2 from c1"? > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.zimm at gmail.com Thu May 11 14:02:17 2017 From: alan.zimm at gmail.com (Alan & Kim Zimmerman) Date: Thu, 11 May 2017 16:02:17 +0200 Subject: [Haskell-cafe] Haskell IDE Engine users? Message-ID: Stupid question, but is anyone using/integrating HIE into anything at the moment? I am considering rearranging the internals to orient it toward being mainly a Language Server Protocol backend , and I want to see who would be affected. Alan -------------- next part -------------- An HTML attachment was scrubbed... URL: From dct25-561bs at mythic-beasts.com Thu May 11 16:12:15 2017 From: dct25-561bs at mythic-beasts.com (David Turner) Date: Thu, 11 May 2017 17:12:15 +0100 Subject: [Haskell-cafe] Fast JSON validation - reducing allocations Message-ID: Dear Café, We have a stream of ~900byte JSON documents (lazy ByteStrings) that we would like to validate (NB not parse) as quickly as possible. We just need to check that the bytes are a syntactically valid JSON document and then pass them elsewhere; we do not care what the content is. The documents are encoded in UTF-8 and have no extraneous whitespace. We have made a number of attempts: 1. Use Aeson to parse the documents and then discard the result. This was actually pretty good: Criterion clocked it at ~30us per document. 2. A hand-written Attoparsec parser. This did quite a bit worse: ~70us per document. 3. Use Get (from the binary package), which was a bit messier as it was factored to avoid all backtracking, but managed to get down to around ~20us per document. 4. Build a table-based, Word8-labelled DFA (with a minor hack to deal with values-within-values) and run it with ByteString.Lazy.foldl'. Also around ~20us per document. We didn't pursue the Attoparsec idea any further, but the other three all allocate ~85kB per document, and this now seems to be the limiting factor for performance. In more detail, looking at the threadscope output, we see it parse 5 or 6 documents in ~150us (allocating ~500kB) and then run the GC, which takes about another 150us. The GC stats indicate that it's only copying a couple of kB of live data each time, so most of that 500kB is junk. Now 85kB per document is ~96B per byte, which is only a pointer-and-a-half. It's not entirely surprising that there's this much allocation going on each time round the loop, but we'd like to try and get rid of it. I've tried the usual strictness tricks and have peered in a mystified fashion at the output of -ddump-simpl but am none the wiser. There's a copy of the relevant code for option 4 at https://github.com/DaveCTurner/json-validator. I've hacked around with it a bit since producing the numbers above, so it's now apparently a bit slower than Aeson but allocates less too (~65kB). Could anyone help, e.g. by pointing me at the bit in the Core that is allocating within the main loop? Many thanks, David -------------- next part -------------- An HTML attachment was scrubbed... URL: From spam at scientician.net Thu May 11 16:30:18 2017 From: spam at scientician.net (Bardur Arantsson) Date: Thu, 11 May 2017 18:30:18 +0200 Subject: [Haskell-cafe] Fast JSON validation - reducing allocations In-Reply-To: References: Message-ID: On 2017-05-11 18:12, David Turner wrote: > Dear Café, > > We have a stream of ~900byte JSON documents (lazy ByteStrings) that we > would like to validate (NB not parse) as quickly as possible. We just > need to check that the bytes are a syntactically valid JSON document and > then pass them elsewhere; we do not care what the content is. The > documents are encoded in UTF-8 and have no extraneous whitespace. > No particular recommendations, but you might want to look into semi-indexing[1] as a strategy. It looks plausible that it would be possible to do that without a lot of allocation; see the paper for details. (I there's also a demo implementation in Python on GH.) [1] http://www.di.unipi.it/~ottavian/files/semi_index_cikm.pdf From dct25-561bs at mythic-beasts.com Thu May 11 16:59:32 2017 From: dct25-561bs at mythic-beasts.com (David Turner) Date: Thu, 11 May 2017 17:59:32 +0100 Subject: [Haskell-cafe] Fast JSON validation - reducing allocations In-Reply-To: References: Message-ID: Interesting, thanks for the link. However we're trying to do _even less_ than that - this is just the "scan the document to produce the Elias-Fano encoding" step, except without needing to keep a hold of it for later. It's not quite as trivial as that paper makes out as (a) it doesn't mention the possibility that the documents might not be well-formed, and (b) it doesn't really talk about dealing with the special delimiting characters within string literals, for which you need to drag along a bunch of state while you're scanning. This'd be pretty trivial to do in a C-like language now we've got the DFA tables built, and I may resort to that at some point if we can't work out how to avoid the allocations in Haskell-land, but I'd quite like to be able to solve problems of this form without unnecessarily resorting to C. Cheers, On 11 May 2017 at 17:30, Bardur Arantsson wrote: > On 2017-05-11 18:12, David Turner wrote: > > Dear Café, > > > > We have a stream of ~900byte JSON documents (lazy ByteStrings) that we > > would like to validate (NB not parse) as quickly as possible. We just > > need to check that the bytes are a syntactically valid JSON document and > > then pass them elsewhere; we do not care what the content is. The > > documents are encoded in UTF-8 and have no extraneous whitespace. > > > > No particular recommendations, but you might want to look into > semi-indexing[1] as a strategy. It looks plausible that it would be > possible to do that without a lot of allocation; see the paper for > details. (I there's also a demo implementation in Python on GH.) > > [1] http://www.di.unipi.it/~ottavian/files/semi_index_cikm.pdf > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From spam at scientician.net Thu May 11 17:11:04 2017 From: spam at scientician.net (Bardur Arantsson) Date: Thu, 11 May 2017 19:11:04 +0200 Subject: [Haskell-cafe] Fast JSON validation - reducing allocations In-Reply-To: References: Message-ID: On 2017-05-11 18:59, David Turner wrote: > Interesting, thanks for the link. However we're trying to do _even less_ > than that - this is just the "scan the document to produce the > Elias-Fano encoding" step, except without needing to keep a hold of it > for later. It's not quite as trivial as that paper makes out as (a) it > doesn't mention the possibility that the documents might not be > well-formed, and (b) it doesn't really talk about dealing with the > special delimiting characters within string literals, for which you need > to drag along a bunch of state while you're scanning. My thinking was actually that it could be used reduce the allocations since everything (AFAIR, it's been a while) would basically just be linear datastructures and indexes. > This'd be pretty trivial to do in a C-like language now we've got the > DFA tables built, and I may resort to that at some point if we can't > work out how to avoid the allocations in Haskell-land, but I'd quite > like to be able to solve problems of this form without unnecessarily > resorting to C. We'll there's always https://hackage.haskell.org/package/inline-c :) Regards, From eric at seidel.io Thu May 11 17:26:49 2017 From: eric at seidel.io (Eric Seidel) Date: Thu, 11 May 2017 10:26:49 -0700 Subject: [Haskell-cafe] Fast JSON validation - reducing allocations In-Reply-To: References: Message-ID: <1494523609.3067104.973553536.32A155B5@webmail.messagingengine.com> On Thu, May 11, 2017, at 09:12, David Turner wrote: > Could anyone help, e.g. by pointing me at the bit in the Core that is > allocating within the main loop? GHC has a -ticky flag that tracks precisely where allocations are happening. It's quite low level (you may have to stare at the STG in addition to the Core to interpret the results) but I've found it incredibly useful when trying to understand performance swings in GHC's own benchmarks. https://ghc.haskell.org/trac/ghc/wiki/Debugging/TickyTicky You can enable it per module, which is nice break from the rebuild-the-world -prof, but the flip side IIRC is that if the allocations are happening in a module that wasn't compiled with -ticky (e.g. somewhere inside Data.Array) you might not see them. Hope this helps! Eric From ben at smart-cactus.org Thu May 11 17:57:58 2017 From: ben at smart-cactus.org (Ben Gamari) Date: Thu, 11 May 2017 13:57:58 -0400 Subject: [Haskell-cafe] Fast JSON validation - reducing allocations In-Reply-To: <1494523609.3067104.973553536.32A155B5@webmail.messagingengine.com> References: <1494523609.3067104.973553536.32A155B5@webmail.messagingengine.com> Message-ID: <87k25ngtsp.fsf@ben-laptop.smart-cactus.org> Eric Seidel writes: > On Thu, May 11, 2017, at 09:12, David Turner wrote: >> Could anyone help, e.g. by pointing me at the bit in the Core that is >> allocating within the main loop? > > GHC has a -ticky flag that tracks precisely where allocations are > happening. It's quite low level (you may have to stare at the STG in > addition to the Core to interpret the results) but I've found it > incredibly useful when trying to understand performance swings in GHC's > own benchmarks. > > https://ghc.haskell.org/trac/ghc/wiki/Debugging/TickyTicky > > You can enable it per module, which is nice break from the > rebuild-the-world -prof, but the flip side IIRC is that if the > allocations are happening in a module that wasn't compiled with -ticky > (e.g. somewhere inside Data.Array) you might not see them. > Indeed, -ticky is wonderful for this sort of thing since it doesn't affect Core-to-Core optimization, meaning that the instrumented program will behave very similarly to the uninstrumented version (just a bit slower due to counter overhead). I had a quick look at your example over lunch. I started like this (after commenting out the aeson benchmark in Main), $ ghc app/Main.hs -isrc -O2 -ddump-stg -fforce-recomp \ -ddump-to-file -dsuppress-idinfo -ddump-simpl -rtsopts \ -ticky -ticky-allocd $ app/Main +RTS -rticky.out This produces a Ticky report (named ticky.out) in the current directory. This includes a table which in my case looked something like, Entries Alloc Alloc'd Non-void Arguments STG Name -------------------------------------------------------------------------------- 123 192 48 1 L go9{v slyX} (main at main:Automaton) 2 0 32 1 L go8{v slyH} (main at main:Automaton) 1465016 58600640 146501600 0 $w$j1{v slMc} (main at main:Automaton) in slHB 161884268 011761148448 0 $w$j1{v slJT} (main at main:Automaton) in slHA 0 0 11720128 4 ppww $s$wgo2{v slHz} (main at main:Automaton) in r4s 16353241111790448768 13185144 5 wwLpp $wgo7{v slHA} (main at main:Automaton) in r4s 1831270 167011824 13185144 6 ppwLww $s$wgo1{v slHB} (main at main:Automaton) in r4s 183127 0 13185144 0 $w$j{v slGN} (main at main:Automaton) in r4s 992 8624 10944 1 L go7{v slwV} (main at main:Automaton) in r4m 3 72 0 1 C main at main:Automaton.showGraph120{v r3O} 681 0 0 2 ML go6{v rkSd} (main at main:Automaton) The important things we care about here are Alloc (that is how many bytes each name allocates) and Alloc'd (that is, how many of each closure are allocated in bytes). [Aside: we explicitly enabled the Alloc'd column during compilation with the -ticky-allocd flag; if you omit it this column will contain only zeros. In general I find it helpful to have so I generally enable it, despite the overhead it introduces.] The table suggests a few nice starting points: $w$j1_slJT is allocated quite a bit, probably by $wgo7_slHA. Next we can turn to the STG output (src/Automaton.dump-stg) to try to understand why this is. Reading STG generally tends to be quite hard due to the rather large, deeply nested trees that most programs compile to. That being said, a good editor can help immensely (I also have my ghc-dump [1] package which I've been meaning to add STG support to, which would enable some interesting analysis techniques). Unfortunately, my lunch is now all gone so I'll have to drop this here for now. However, I'll try to pick it up again tonight. Do keep us apprised of your progress! Cheers, - Ben [1] https://github.com/bgamari/ghc-dump -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 487 bytes Desc: not available URL: From ben at smart-cactus.org Thu May 11 18:40:14 2017 From: ben at smart-cactus.org (Ben Gamari) Date: Thu, 11 May 2017 14:40:14 -0400 Subject: [Haskell-cafe] Fast JSON validation - reducing allocations In-Reply-To: References: Message-ID: <87bmqzgru9.fsf@ben-laptop.smart-cactus.org> Ccing Luke Maurer under the assumption that he will appreciate seeing the fruits of his labor. David Turner writes: > Dear Café, > (snip) > > There's a copy of the relevant code for option 4 at > https://github.com/DaveCTurner/json-validator. I've hacked around with it a > bit since producing the numbers above, so it's now apparently a bit slower > than Aeson but allocates less too (~65kB). > > Could anyone help, e.g. by pointing me at the bit in the Core that is > allocating within the main loop? > While turning this over in my head I realized that this is the sort of program which may be helped significantly by GHC 8.2's improved join point handling. Indeed the timings seem to support this hypothesis: GHC 8.0.2 benchmarking json-validator/Automaton/testEvent time 22.84 μs (22.76 μs .. 22.94 μs) 1.000 R² (1.000 R² .. 1.000 R²) mean 22.84 μs (22.76 μs .. 22.94 μs) std dev 297.4 ns (221.8 ns .. 378.8 ns) Alloc rate 4,015,256,078,038 bytes per MUT second GHC 8.2 benchmarking json-validator/Automaton/testEvent time 9.221 μs (9.141 μs .. 9.318 μs) 0.998 R² (0.996 R² .. 1.000 R²) mean 9.163 μs (9.084 μs .. 9.356 μs) std dev 399.8 ns (193.0 ns .. 745.4 ns) variance introduced by outliers: 54% (severely inflated) Alloc rate 123,141,635 bytes per MUT second Wow! I suspect your allocations have now vanished. I didn't verify that the improvement really was due to more join points, but it seems quite likely. Well done Luke! Cheers, - Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 487 bytes Desc: not available URL: From dct25-561bs at mythic-beasts.com Thu May 11 18:56:00 2017 From: dct25-561bs at mythic-beasts.com (David Turner) Date: Thu, 11 May 2017 19:56:00 +0100 Subject: [Haskell-cafe] Fast JSON validation - reducing allocations In-Reply-To: References: <87bmqzgru9.fsf@ben-laptop.smart-cactus.org> Message-ID: Ben, Eric, thanks for your help. A whole new world of low-level statistics opens up before me... On 11 May 2017 at 18:57, Ben Gamari wrote: > Eric Seidel writes: > > > On Thu, May 11, 2017, at 09:12, David Turner wrote: > >> Could anyone help, e.g. by pointing me at the bit in the Core that is > >> allocating within the main loop? > > > > GHC has a -ticky flag that tracks precisely where allocations are > > happening. It's quite low level (you may have to stare at the STG in > > addition to the Core to interpret the results) but I've found it > > incredibly useful when trying to understand performance swings in GHC's > > own benchmarks. > > > > https://ghc.haskell.org/trac/ghc/wiki/Debugging/TickyTicky > > > > You can enable it per module, which is nice break from the > > rebuild-the-world -prof, but the flip side IIRC is that if the > > allocations are happening in a module that wasn't compiled with -ticky > > (e.g. somewhere inside Data.Array) you might not see them. > > Indeed, -ticky is wonderful for this sort of thing since it doesn't > affect Core-to-Core optimization, meaning that the instrumented program > will behave very similarly to the uninstrumented version (just a bit > slower due to counter overhead). > > I had a quick look at your example over lunch. I started like this > (after commenting out the aeson benchmark in Main), > > $ ghc app/Main.hs -isrc -O2 -ddump-stg -fforce-recomp \ > -ddump-to-file -dsuppress-idinfo -ddump-simpl -rtsopts \ > -ticky -ticky-allocd > $ app/Main +RTS -rticky.out Ok, I was just about to ask about the Alloc'd column as mine was all zeroes, but the -ticky-allocd was what I needed, thanks. > The table suggests a few nice starting points: $w$j1_slJT is allocated > quite a bit, probably by $wgo7_slHA. Next we can turn to the STG output > (src/Automaton.dump-stg) to try to understand why this is. Reading STG > generally tends to be quite hard due to the rather large, deeply nested > trees that most programs compile to. You're not wrong. I've trawled through the STG as best as I can for a newbie. The function with a large number in the 'Alloc' column looks pretty much to be the heart of the `step` function. There's a lot of nesting but it looks largely to be just checking the bounds on array indices, which I don't think allocates anything. However I see this this little snippet at the very bottom of the nesting: case indexArray# [ds1_sl1b y2_sl5H] of _ [Occ=Dead] { (##) ipv8_sl60 [Occ=Once!] -> case ipv8_sl60 of _ [Occ=Dead] { GHC.Word.W8# dt6_sl62 [Occ=Once] -> case ss_sl5v of dt7_sl63 { __DEFAULT -> (#,,#) [__word 1 dt6_sl62 dt7_sl63]; }; }; }; I'm guessing that the `indexArray` call is the line that reads `nextState = aTransitionsTable makeAutomaton AU.! (currentState, nextByte)`, and to me it looks like it might be unboxing the thing it's getting out of the array. Not sure that counts as an allocation, but I'm surprised anyway. I'll keep digging anyway, but it'd be good to hear of any progress at your end too. Hope it didn't spoil your lunch! Cheers, > While turning this over in my head I realized that this is the sort of > program which may be helped significantly by GHC 8.2's improved join > point handling. Indeed the timings seem to support this hypothesis: > > GHC 8.0.2 > > benchmarking json-validator/Automaton/testEvent > time 22.84 μs (22.76 μs .. 22.94 μs) > 1.000 R² (1.000 R² .. 1.000 R²) > mean 22.84 μs (22.76 μs .. 22.94 μs) > std dev 297.4 ns (221.8 ns .. 378.8 ns) > > Alloc rate 4,015,256,078,038 bytes per MUT second > > GHC 8.2 > > benchmarking json-validator/Automaton/testEvent > time 9.221 μs (9.141 μs .. 9.318 μs) > 0.998 R² (0.996 R² .. 1.000 R²) > mean 9.163 μs (9.084 μs .. 9.356 μs) > std dev 399.8 ns (193.0 ns .. 745.4 ns) > variance introduced by outliers: 54% (severely inflated) > > Alloc rate 123,141,635 bytes per MUT second > > > Wow! I suspect your allocations have now vanished. Ooo, that's more like it. Could you run again using the following to get Criterion's estimate of the allocations-per-call? json-validator-exe --regress allocated:iters +RTS -T Cheers, David On 11 May 2017 at 19:45, David Turner wrote: > On 11 May 2017 at 19:40, Ben Gamari wrote: > >> Ccing Luke Maurer under the assumption that he will appreciate seeing >> the fruits of his labor. >> >> >> David Turner writes: >> >> > Dear Café, >> > >> (snip) >> > >> > There's a copy of the relevant code for option 4 at >> > https://github.com/DaveCTurner/json-validator. I've hacked around with >> it a >> > bit since producing the numbers above, so it's now apparently a bit >> slower >> > than Aeson but allocates less too (~65kB). >> > >> > Could anyone help, e.g. by pointing me at the bit in the Core that is >> > allocating within the main loop? >> > >> While turning this over in my head I realized that this is the sort of >> program which may be helped significantly by GHC 8.2's improved join >> point handling. Indeed the timings seem to support this hypothesis: >> >> GHC 8.0.2 >> >> benchmarking json-validator/Automaton/testEvent >> time 22.84 μs (22.76 μs .. 22.94 μs) >> 1.000 R² (1.000 R² .. 1.000 R²) >> mean 22.84 μs (22.76 μs .. 22.94 μs) >> std dev 297.4 ns (221.8 ns .. 378.8 ns) >> >> Alloc rate 4,015,256,078,038 bytes per MUT second >> >> GHC 8.2 >> >> benchmarking json-validator/Automaton/testEvent >> time 9.221 μs (9.141 μs .. 9.318 μs) >> 0.998 R² (0.996 R² .. 1.000 R²) >> mean 9.163 μs (9.084 μs .. 9.356 μs) >> std dev 399.8 ns (193.0 ns .. 745.4 ns) >> variance introduced by outliers: 54% (severely inflated) >> >> Alloc rate 123,141,635 bytes per MUT second >> >> >> Wow! I suspect your allocations have now vanished. >> > > > Ooo, that's more like it. > > Could you run again using the following to get Criterion's estimate of the > allocations-per-call? > > json-validator-exe --regress allocated:iters +RTS -T > > Cheers, > > David > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ben at smart-cactus.org Thu May 11 19:32:41 2017 From: ben at smart-cactus.org (Ben Gamari) Date: Thu, 11 May 2017 15:32:41 -0400 Subject: [Haskell-cafe] Fast JSON validation - reducing allocations In-Reply-To: References: <1494523609.3067104.973553536.32A155B5@webmail.messagingengine.com> <87k25ngtsp.fsf@ben-laptop.smart-cactus.org> Message-ID: <878tm3gpeu.fsf@ben-laptop.smart-cactus.org> David Turner writes: > Ben, Eric, thanks for your help. A whole new world of low-level statistics > opens up before me... > No worries! > You're not wrong. > > I've trawled through the STG as best as I can for a newbie. The function > with a large number in the 'Alloc' column looks pretty much to be the heart > of the `step` function. There's a lot of nesting but it looks largely to be > just checking the bounds on array indices, which I don't think allocates > anything. > Something that I should have mentioned earlier is that STG has the nice property that all allocation is syntactically obvious: allocated closures manifest as `let`s. This makes it fairly easy to pick out possible allocation sites, even in large dumps. > However I see this this little snippet at the very bottom of the nesting: > > case > indexArray# [ds1_sl1b > y2_sl5H] > of > _ [Occ=Dead] > { (##) ipv8_sl60 [Occ=Once!] -> > case > ipv8_sl60 > of > _ [Occ=Dead] > { GHC.Word.W8# dt6_sl62 [Occ=Once] -> > case > ss_sl5v > of > dt7_sl63 > { __DEFAULT -> > (#,,#) [__word 1 > dt6_sl62 > dt7_sl63]; > }; > }; > }; > > > I'm guessing that the `indexArray` call is the line that reads `nextState = > aTransitionsTable makeAutomaton AU.! (currentState, nextByte)`, and to me > it looks like it might be unboxing the thing it's getting out of the array. > Not sure that counts as an allocation, but I'm surprised anyway. > The unboxing should just involve looking at the value field of the W8# closure (e.g. a memory dereference) and putting the value in a machine register. There is no allocation here as far as I can see. > I'll keep digging anyway, but it'd be good to hear of any progress at your > end too. Hope it didn't spoil your lunch! Far from it! It was nice to have a puzzle to ponder. Cheers, - Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 487 bytes Desc: not available URL: From dct25-561bs at mythic-beasts.com Fri May 12 08:10:50 2017 From: dct25-561bs at mythic-beasts.com (David Turner) Date: Fri, 12 May 2017 09:10:50 +0100 Subject: [Haskell-cafe] Fast JSON validation - reducing allocations In-Reply-To: <878tm3gpeu.fsf@ben-laptop.smart-cactus.org> References: <1494523609.3067104.973553536.32A155B5@webmail.messagingengine.com> <87k25ngtsp.fsf@ben-laptop.smart-cactus.org> <878tm3gpeu.fsf@ben-laptop.smart-cactus.org> Message-ID: Morning all, On 11 May 2017 at 20:32, Ben Gamari wrote: > > Something that I should have mentioned earlier is that STG has the nice > property that all allocation is syntactically obvious: allocated > closures manifest as `let`s. This makes it fairly easy to pick out > possible allocation sites, even in large dumps. > Ah, that's very useful to know! Armed with that knowledge, I came to the conclusion that the allocation was for the sharing of the `nextState` variable. Inlining it brings it down to 20us and 22kB per iteration. https://github.com/DaveCTurner/json-validator/commit/ec994ec9226ca7bc2e76f19bef98f42e0b233524 Getting closer, but it looks like waiting for 8.2 is a better answer. Looking forward to it! Cheers, -------------- next part -------------- An HTML attachment was scrubbed... URL: From arjenvanweelden at gmail.com Fri May 12 08:27:40 2017 From: arjenvanweelden at gmail.com (Arjen) Date: Fri, 12 May 2017 10:27:40 +0200 Subject: [Haskell-cafe] Fast JSON validation - reducing allocations In-Reply-To: References: <1494523609.3067104.973553536.32A155B5@webmail.messagingengine.com> <87k25ngtsp.fsf@ben-laptop.smart-cactus.org> <878tm3gpeu.fsf@ben-laptop.smart-cactus.org> Message-ID: <1494577660.20209.1.camel@gmail.com> On Fri, 2017-05-12 at 09:10 +0100, David Turner wrote: > Morning all, > > On 11 May 2017 at 20:32, Ben Gamari wrote: > > Something that I should have mentioned earlier is that STG has the > > nice > > property that all allocation is syntactically obvious: allocated > > closures manifest as `let`s. This makes it fairly easy to pick out > > possible allocation sites, even in large dumps. > > > Ah, that's very useful to know! > > Armed with that knowledge, I came to the conclusion that the > allocation was for the sharing of the `nextState` variable. Inlining > it brings it down to 20us and 22kB per iteration. > > https://github.com/DaveCTurner/json-validator/commit/ec994ec9226ca7bc > 2e76f19bef98f42e0b233524 > > Getting closer, but it looks like waiting for 8.2 is a better answer. > Looking forward to it! > > Cheers, > Maybe this is a silly question, and please let me know why if so, but: Has anyone thought about parallelizing it for multiple messages in order to "produce garbage faster"? While reducing allocation will make the single validations faster, doing multiple ones might improve the throughput per GC ratio. This assumes that the amount of live data in the heap is small, making GC sort of constant time, and having multiple cores available. I wonder whether a few strategically placed par's and pseq's might allow you to scale horizontally without requiring invasive changes to the program's structure. Apologies for not trying to do this myself first ;-). kind regards, Arjen From dct25-561bs at mythic-beasts.com Fri May 12 09:48:01 2017 From: dct25-561bs at mythic-beasts.com (David Turner) Date: Fri, 12 May 2017 10:48:01 +0100 Subject: [Haskell-cafe] Fast JSON validation - reducing allocations In-Reply-To: <1494577660.20209.1.camel@gmail.com> References: <1494523609.3067104.973553536.32A155B5@webmail.messagingengine.com> <87k25ngtsp.fsf@ben-laptop.smart-cactus.org> <878tm3gpeu.fsf@ben-laptop.smart-cactus.org> <1494577660.20209.1.camel@gmail.com> Message-ID: On 12 May 2017 at 09:27, Arjen wrote: > > Maybe this is a silly question, and please let me know why if so, but: > > Has anyone thought about parallelizing it for multiple messages in > order to "produce garbage faster"? While reducing allocation will make > the single validations faster, doing multiple ones might improve the > throughput per GC ratio. This assumes that the amount of live data in > the heap is small, making GC sort of constant time, and having multiple > cores available. > Not a silly question at all. Adding the following incantation: `using` parListChunk 100 rseq does quite happily spread things across all 4 cores on my development machine, and it's certainly a bit faster. To give some stats, it processes ~24 events between GCs rather than ~6, and collects ~2MB rather than ~500kB. The throughput becomes a lot less consistent, however, at least partly due to some bigger GC pauses along the way. As Ben's statistics showed, our allocation rate on one thread is around 4TBps, which is already stressing the GC out a bit, and parallelising it doesn't make that problem any easier. I know in the OP I said "we have a stream" (accidental MLK misquote) but in fact there are a bunch of parallel streams whose number exceeds the number of available cores, so we don't anticipate any enormous benefit from spreading the processing of any one stream across multiple cores: single-threaded performance is what we think we should be concentrating on. Cheers, David -------------- next part -------------- An HTML attachment was scrubbed... URL: From arjenvanweelden at gmail.com Fri May 12 09:52:04 2017 From: arjenvanweelden at gmail.com (Arjen) Date: Fri, 12 May 2017 11:52:04 +0200 Subject: [Haskell-cafe] Fast JSON validation - reducing allocations In-Reply-To: <1494577660.20209.1.camel@gmail.com> References: <1494523609.3067104.973553536.32A155B5@webmail.messagingengine.com> <87k25ngtsp.fsf@ben-laptop.smart-cactus.org> <878tm3gpeu.fsf@ben-laptop.smart-cactus.org> <1494577660.20209.1.camel@gmail.com> Message-ID: <1494582724.20209.3.camel@gmail.com> On Fri, 2017-05-12 at 10:27 +0200, Arjen wrote: > On Fri, 2017-05-12 at 09:10 +0100, David Turner wrote: > > Morning all, > >  > > On 11 May 2017 at 20:32, Ben Gamari wrote: > > > Something that I should have mentioned earlier is that STG has > the > > > nice > > > property that all allocation is syntactically obvious: allocated > > > closures manifest as `let`s. This makes it fairly easy to pick > out > > > possible allocation sites, even in large dumps. > >  > >  > > Ah, that's very useful to know! > >  > > Armed with that knowledge, I came to the conclusion that the > > allocation was for the sharing of the `nextState` variable. > Inlining > > it brings it down to 20us and 22kB per iteration. > >  > > https://github.com/DaveCTurner/json-validator/commit/ec994ec9226ca7 > bc > > 2e76f19bef98f42e0b233524 > >  > > Getting closer, but it looks like waiting for 8.2 is a better > answer. > > Looking forward to it! > >  > > Cheers, > >  > > Maybe this is a silly question, and please let me know why if so, > but: > > Has anyone thought about parallelizing it for multiple messages in > order to "produce garbage faster"? While reducing allocation will > make > the single validations faster, doing multiple ones might improve the > throughput per GC ratio. This assumes that the amount of live data in > the heap is small, making GC sort of constant time, and having > multiple > cores available. > > I wonder whether a few strategically placed par's and pseq's might > allow you to scale horizontally without requiring invasive changes to > the program's structure. Apologies for not trying to do this myself > first ;-). > Unfortunately, this does not seem to help. I tried it and while I did see 3.5 and 3.95 CPU's used with parList and parListChunk 8, the timings show it to be slower than sequential evaluation of a list of testEvent. Thank you for the problem to try this on :-) Please let me know if I made a mistake in the testing code below. kind regards, Arjen ---8<--- benchmarking json-validator/Automaton/testEvent time                 26.57 μs   (26.07 μs .. 27.12 μs)                      0.987 R²   (0.973 R² .. 0.995 R²) mean                 31.01 μs   (28.17 μs .. 44.49 μs) std dev              15.65 μs   (5.258 μs .. 35.77 μs) variance introduced by outliers: 99% (severely inflated) benchmarking json-validator/Automaton-List/testEventList time                 65.11 ms   (61.54 ms .. 69.54 ms)                      0.982 R²   (0.951 R² .. 0.996 R²) mean                 59.18 ms   (56.28 ms .. 63.22 ms) std dev              5.801 ms   (4.344 ms .. 8.238 ms) variance introduced by outliers: 32% (moderately inflated) benchmarking json-validator/Automaton-ParList/testEventList time                 243.9 ms   (214.9 ms .. 270.6 ms)                      0.996 R²   (0.986 R² .. 1.000 R²) mean                 253.7 ms   (243.6 ms .. 260.8 ms) std dev              10.32 ms   (6.781 ms .. 13.19 ms) variance introduced by outliers: 16% (moderately inflated) benchmarking json-validator/Automaton-ParListChunk/testEventList time                 211.4 ms   (193.1 ms .. 232.3 ms)                      0.997 R²   (0.990 R² .. 1.000 R²) mean                 200.3 ms   (193.0 ms .. 206.6 ms) std dev              9.256 ms   (7.106 ms .. 10.21 ms) variance introduced by outliers: 14% (moderately inflated)   19,225,632,224 bytes allocated in the heap      109,968,376 bytes copied during GC        2,062,736 bytes maximum residency (20 sample(s))        2,250,352 bytes maximum slop               10 MB total memory in use (0 MB lost due to fragmentation)                                      Tot time (elapsed)  Avg pause  Max pause   Gen  0     28722 colls, 28722 par   17.829s   1.591s     0.0001s    0.0160s   Gen  1        20 colls,    19 par    0.255s   0.054s     0.0027s    0.0058s   Parallel GC work balance: 7.41% (serial 0%, perfect 100%)   TASKS: 13 (1 bound, 12 peak workers (12 total), using -N4)   SPARKS: 25625 (25570 converted, 0 overflowed, 0 dud, 20 GC'd, 35 fizzled)   INIT    time    0.001s  (  0.002s elapsed)   MUT     time   44.403s  ( 22.013s elapsed)   GC      time   18.084s  (  1.645s elapsed)   EXIT    time    0.001s  (  0.001s elapsed)   Total   time   62.490s  ( 23.660s elapsed)   Alloc rate    432,981,654 bytes per MUT second   Productivity  71.1% of total user, 93.0% of total elapsed gc_alloc_block_sync: 25370 whitehole_spin: 0 gen[0].sync: 405 gen[1].sync: 22 ---8<--- {-# LANGUAGE OverloadedStrings #-} module Main where import           Criterion.Main import           Data.Aeson import qualified Data.ByteString.Lazy as BL import qualified Data.Text.Encoding   as T import qualified Data.Text.IO as T import qualified Data.Text as T (append, pack) import qualified Automaton import Control.Parallel.Strategies testEvent :: Int -> BL.ByteString testEvent i = BL.fromStrict $ T.encodeUtf8 (T.append "{\"stream\":\"actuals- stream\",\"submitter\":{\"type\":\"other\",\"description\":\"redactedre dac\"},\"driverActivities\":[{\"driverActivity\":{\"journey\":{\"headco de\":\"1A01\",\"description\":\"redactedredactedredactedredactedredacte dredacte\"},\"activity\":[{\"arrivalTime\":null,\"sequence\":1,\"tiploc \":\"REDACTE\",\"stop\":true,\"departureTime\":\"2016-06- 09T18:22:28.000000000000Z\"},{\"arrivalTime\":\"2016-06- 09T18:24:43.000000000000Z\",\"sequence\":2,\"tiploc\":\"REDACTE\",\"sto p\":true,\"departureTime\":\"2016-06- 09T18:25:51.000000000000Z\"},{\"arrivalTime\":\"2016-06- 09T18:26:58.000000000000Z\",\"sequence\":3,\"tiploc\":\"REDACT\",\"stop \":true,\"departureTime\":\"2016-06- 09T18:28:08.000000000000Z\"},{\"arrivalTime\":\"2016-06- 09T18:29:57.000000000000Z\",\"sequence\":4,\"tiploc\":\"REDACTE\",\"sto p\":true,\"departureTime\":null}]},\"activityUserId\":\"521be60a-02f2- 4892-b468-c17d9c1c4fcf\"}],\"submissionTime\":\"2016-06- 09T18:36:45.831486000000Z\",\"type\":\"driverActivityLogged" (T.append (T.pack (show i)) "\"}")) data AnyJSON = AnyJSON   deriving (Show, Eq) instance FromJSON AnyJSON where   parseJSON _ = pure AnyJSON main :: IO () main = print (testEventList [0]) >> defaultMain   [ bgroup "json-validator/Automaton"     [ bench "testEvent" $ whnf Automaton.isValidJson (testEvent 0)     ]   , bgroup "json-validator/Automaton-List"     [ bench "testEventList" $ whnf (\es -> and (testEventList es `using` rseq)) [1..1000]     ]   , bgroup "json-validator/Automaton-ParList"     [ bench "testEventList" $ whnf (\es -> and (testEventList es `using` parList rseq)) [1..1000]     ]   , bgroup "json-validator/Automaton-ParListChunk"     [ bench "testEventList" $ whnf (\es -> and (testEventList es `using` parListChunk 8 rseq)) [1..1000]     ]   ]   where     testEventList = map (Automaton.isValidJson . testEvent) From arjenvanweelden at gmail.com Fri May 12 10:00:02 2017 From: arjenvanweelden at gmail.com (Arjen) Date: Fri, 12 May 2017 12:00:02 +0200 Subject: [Haskell-cafe] Fast JSON validation - reducing allocations In-Reply-To: References: <1494523609.3067104.973553536.32A155B5@webmail.messagingengine.com> <87k25ngtsp.fsf@ben-laptop.smart-cactus.org> <878tm3gpeu.fsf@ben-laptop.smart-cactus.org> <1494577660.20209.1.camel@gmail.com> Message-ID: <1494583202.20209.5.camel@gmail.com> On Fri, 2017-05-12 at 10:48 +0100, David Turner wrote: > On 12 May 2017 at 09:27, Arjen wrote: > > Maybe this is a silly question, and please let me know why if so, > > but: > > > > Has anyone thought about parallelizing it for multiple messages in > > order to "produce garbage faster"? While reducing allocation will > > make > > the single validations faster, doing multiple ones might improve > > the > > throughput per GC ratio. This assumes that the amount of live data > > in > > the heap is small, making GC sort of constant time, and having > > multiple > > cores available. > > Not a silly question at all. Adding the following incantation: > >     `using` parListChunk 100 rseq > > does quite happily spread things across all 4 cores on my development > machine, and it's certainly a bit faster. To give some stats, it > processes ~24 events between GCs rather than ~6, and collects ~2MB > rather than ~500kB. The throughput becomes a lot less consistent, > however, at least partly due to some bigger GC pauses along the way. > As Ben's statistics showed, our allocation rate on one thread is > around 4TBps, which is already stressing the GC out a bit, and > parallelising it doesn't make that problem any easier. > > I know in the OP I said "we have a stream" (accidental MLK misquote) > but in fact there are a bunch of parallel streams whose number > exceeds the number of available cores, so we don't anticipate any > enormous benefit from spreading the processing of any one stream > across multiple cores: single-threaded performance is what we think > we should be concentrating on. > > Cheers, > > David > Happy to read that you have more success than I with parListChunk. I expect(ed) the sparks to be cheap, so this might help if the various incoming streams are very unbalanced in length and/or message sizes. I agree that multi-processing a single stream does not make much sense if you already have multiple concurrent streams. Nice to see that adding on parallelism in Haskell (GHC) is that easy (in this case) and with a very good speed-up factor! kind regards, Arjen From arjenvanweelden at gmail.com Fri May 12 10:16:45 2017 From: arjenvanweelden at gmail.com (Arjen) Date: Fri, 12 May 2017 12:16:45 +0200 Subject: [Haskell-cafe] Fast JSON validation - reducing allocations In-Reply-To: References: <1494523609.3067104.973553536.32A155B5@webmail.messagingengine.com> <87k25ngtsp.fsf@ben-laptop.smart-cactus.org> <878tm3gpeu.fsf@ben-laptop.smart-cactus.org> <1494577660.20209.1.camel@gmail.com> Message-ID: <1494584205.20209.7.camel@gmail.com> On Fri, 2017-05-12 at 10:48 +0100, David Turner wrote: > On 12 May 2017 at 09:27, Arjen wrote: > > Maybe this is a silly question, and please let me know why if so, > > but: > > > > Has anyone thought about parallelizing it for multiple messages in > > order to "produce garbage faster"? While reducing allocation will > > make > > the single validations faster, doing multiple ones might improve > > the > > throughput per GC ratio. This assumes that the amount of live data > > in > > the heap is small, making GC sort of constant time, and having > > multiple > > cores available. > > Not a silly question at all. Adding the following incantation: > >     `using` parListChunk 100 rseq > > does quite happily spread things across all 4 cores on my development > machine, and it's certainly a bit faster. To give some stats, it > processes ~24 events between GCs rather than ~6, and collects ~2MB > rather than ~500kB. The throughput becomes a lot less consistent, > however, at least partly due to some bigger GC pauses along the way. > As Ben's statistics showed, our allocation rate on one thread is > around 4TBps, which is already stressing the GC out a bit, and > parallelising it doesn't make that problem any easier. > > I know in the OP I said "we have a stream" (accidental MLK misquote) > but in fact there are a bunch of parallel streams whose number > exceeds the number of available cores, so we don't anticipate any > enormous benefit from spreading the processing of any one stream > across multiple cores: single-threaded performance is what we think > we should be concentrating on. > > Cheers, > > David > Apologies for spamming, but if you want more mutator time between garbage collections, try increasing the nursery size. I get a lot less time in GC and also much less sync's on GC (according to -s). It seems to reduce the execution time by a third using something -A8M or -A64M (quite extreem). In a large program, this effect might be less. kind regards, Arjen From dct25-561bs at mythic-beasts.com Fri May 12 10:24:23 2017 From: dct25-561bs at mythic-beasts.com (David Turner) Date: Fri, 12 May 2017 11:24:23 +0100 Subject: [Haskell-cafe] Fast JSON validation - reducing allocations In-Reply-To: <1494583202.20209.5.camel@gmail.com> References: <1494523609.3067104.973553536.32A155B5@webmail.messagingengine.com> <87k25ngtsp.fsf@ben-laptop.smart-cactus.org> <878tm3gpeu.fsf@ben-laptop.smart-cactus.org> <1494577660.20209.1.camel@gmail.com> <1494583202.20209.5.camel@gmail.com> Message-ID: On 12 May 2017 at 11:00, Arjen wrote: > Happy to read that you have more success than I with parListChunk. > I expect(ed) the sparks to be cheap, so this might help if the various > incoming streams are very unbalanced in length and/or message sizes. > I agree that multi-processing a single stream does not make much sense > if you already have multiple concurrent streams. > > Nice to see that adding on parallelism in Haskell (GHC) is that easy > (in this case) and with a very good speed-up factor! > > kind regards, Arjen > Ah, ok, this is strange. The production system is definitely faster with the parallel strategy (on one stream) but my Criterion benchmarks are much slower. I've updated the code and results on Github ( https://github.com/DaveCTurner/json-validator). Probably not going to be able to look at the parallel version much more, but thought you might like a look. Cheers, -------------- next part -------------- An HTML attachment was scrubbed... URL: From anthony_clayden at clear.net.nz Fri May 12 10:46:45 2017 From: anthony_clayden at clear.net.nz (Anthony Clayden) Date: Fri, 12 May 2017 22:46:45 +1200 Subject: [Haskell-cafe] [ghc-proposals/cafe] Partially applied type families Message-ID: <59159295.24b.73e9.13590@clear.net.nz> > 2 days ago Richard Eisenberg (and mniip) wrote: > ... > On incremental improvements / the "half-baked" nature of > type families: I agree completely. ... ["half-baked" is Richard quoting mniip] > ... the weird place of type families in the language. > It is my hope that Dependent Haskell will obviate > a lot of these concerns, allowing us to deprecate > type families as we know them > (you would just use an ordinary function in types > instead). I don't want to sidetrack the github discussion on mniip's proposal. https://github.com/ghc-proposals/ghc-proposals/pull/52 So please explain here in what way type families are "half baked". The part of type families I find hard to use and hard to reason about is closed type families. I'd be very happy to deprecate them, if there was something that did overlaps better. >From what I can make out, though, in Richard's Dissertation, they can't be promoted to "ordinary functions in types". If the closed equations were ordinary functions in types, you could go: > type family F a b > type instance F Int b = b > type instance F a Bool | a /~ Int = a > -- non-unifiability guard With no need for a closed sequence of choices. Is this the "case-like computations" others talk about on the proposal? AntC From chow.soham at gmail.com Fri May 12 12:31:05 2017 From: chow.soham at gmail.com (Soham Chowdhury) Date: Fri, 12 May 2017 12:31:05 +0000 Subject: [Haskell-cafe] Partially applied type families In-Reply-To: References: Message-ID: Relatedly, there is a sketch of something like a "case construct" on Richard's blog, where he talks about a "type instance where" syntax that allows closed interdependent sets of family instances. Is that something that was later found to be infeasible? On Fri, May 12, 2017, 17:53 wrote: > Send Haskell-Cafe mailing list submissions to > haskell-cafe at haskell.org > > To subscribe or unsubscribe via the World Wide Web, visit > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > or, via email, send a message with subject or body 'help' to > haskell-cafe-request at haskell.org > > You can reach the person managing the list at > haskell-cafe-owner at haskell.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Haskell-Cafe digest..." > Today's Topics: > > 1. Re: Fast JSON validation - reducing allocations (Arjen) > 2. Re: Fast JSON validation - reducing allocations (David Turner) > 3. Re: [ghc-proposals/cafe] Partially applied type families > (Anthony Clayden) > > > > ---------- Forwarded message ---------- > From: Arjen > To: David Turner , Haskell Cafe < > haskell-cafe at haskell.org> > Cc: > Bcc: > Date: Fri, 12 May 2017 12:16:45 +0200 > Subject: Re: [Haskell-cafe] Fast JSON validation - reducing allocations > On Fri, 2017-05-12 at 10:48 +0100, David Turner wrote: > > On 12 May 2017 at 09:27, Arjen wrote: > > > Maybe this is a silly question, and please let me know why if so, > > > but: > > > > > > Has anyone thought about parallelizing it for multiple messages in > > > order to "produce garbage faster"? While reducing allocation will > > > make > > > the single validations faster, doing multiple ones might improve > > > the > > > throughput per GC ratio. This assumes that the amount of live data > > > in > > > the heap is small, making GC sort of constant time, and having > > > multiple > > > cores available. > > > > Not a silly question at all. Adding the following incantation: > > > > `using` parListChunk 100 rseq > > > > does quite happily spread things across all 4 cores on my development > > machine, and it's certainly a bit faster. To give some stats, it > > processes ~24 events between GCs rather than ~6, and collects ~2MB > > rather than ~500kB. The throughput becomes a lot less consistent, > > however, at least partly due to some bigger GC pauses along the way. > > As Ben's statistics showed, our allocation rate on one thread is > > around 4TBps, which is already stressing the GC out a bit, and > > parallelising it doesn't make that problem any easier. > > > > I know in the OP I said "we have a stream" (accidental MLK misquote) > > but in fact there are a bunch of parallel streams whose number > > exceeds the number of available cores, so we don't anticipate any > > enormous benefit from spreading the processing of any one stream > > across multiple cores: single-threaded performance is what we think > > we should be concentrating on. > > > > Cheers, > > > > David > > > Apologies for spamming, but if you want more mutator time between > garbage collections, try increasing the nursery size. I get a lot less > time in GC and also much less sync's on GC (according to -s). It seems > to reduce the execution time by a third using something -A8M or -A64M > (quite extreem). In a large program, this effect might be less. > > kind regards, Arjen > > > > > > > ---------- Forwarded message ---------- > From: David Turner > To: Arjen > Cc: Haskell Cafe > Bcc: > Date: Fri, 12 May 2017 11:24:23 +0100 > Subject: Re: [Haskell-cafe] Fast JSON validation - reducing allocations > On 12 May 2017 at 11:00, Arjen wrote: > >> Happy to read that you have more success than I with parListChunk. >> I expect(ed) the sparks to be cheap, so this might help if the various >> incoming streams are very unbalanced in length and/or message sizes. >> I agree that multi-processing a single stream does not make much sense >> if you already have multiple concurrent streams. >> >> Nice to see that adding on parallelism in Haskell (GHC) is that easy >> (in this case) and with a very good speed-up factor! >> >> kind regards, Arjen >> > > Ah, ok, this is strange. The production system is definitely faster with > the parallel strategy (on one stream) but my Criterion benchmarks are much > slower. I've updated the code and results on Github ( > https://github.com/DaveCTurner/json-validator). Probably not going to be > able to look at the parallel version much more, but thought you might like > a look. > > Cheers, > > > > > ---------- Forwarded message ---------- > From: Anthony Clayden > To: haskell-cafe at haskell.org > Cc: > Bcc: > Date: Fri, 12 May 2017 22:46:45 +1200 > Subject: Re: [Haskell-cafe] [ghc-proposals/cafe] Partially applied type > families > > 2 days ago Richard Eisenberg (and mniip) wrote: > > > ... > > On incremental improvements / the "half-baked" nature of > > type families: I agree completely. ... > ["half-baked" is Richard quoting mniip] > > > ... the weird place of type families in the language. > > It is my hope that Dependent Haskell will obviate > > a lot of these concerns, allowing us to deprecate > > type families as we know them > > (you would just use an ordinary function in types > > instead). > > I don't want to sidetrack the github discussion > on mniip's proposal. > https://github.com/ghc-proposals/ghc-proposals/pull/52 > > So please explain here in what way > type families are "half baked". > > The part of type families I find > hard to use and hard to reason about > is closed type families. > I'd be very happy to deprecate them, > if there was something that did overlaps better. > > >From what I can make out, though, > in Richard's Dissertation, > they can't be promoted to "ordinary functions > in types". > > If the closed equations were ordinary > functions in types, you could go: > > > type family F a b > > type instance F Int b = b > > type instance F a Bool | a /~ Int = a > > -- non-unifiability guard > > With no need for a closed sequence of choices. > > Is this the "case-like computations" > others talk about on the proposal? > > > AntC > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ben at smart-cactus.org Fri May 12 13:10:18 2017 From: ben at smart-cactus.org (Ben Gamari) Date: Fri, 12 May 2017 09:10:18 -0400 Subject: [Haskell-cafe] Fast JSON validation - reducing allocations In-Reply-To: References: <87bmqzgru9.fsf@ben-laptop.smart-cactus.org> Message-ID: <874lwqgr0l.fsf@ben-laptop.smart-cactus.org> David Turner writes: > On 11 May 2017 at 19:40, Ben Gamari wrote: > >> Ccing Luke Maurer under the assumption that he will appreciate seeing >> the fruits of his labor. >> >> >> David Turner writes: >> >> > Dear Café, >> > >> (snip) >> > >> > There's a copy of the relevant code for option 4 at >> > https://github.com/DaveCTurner/json-validator. I've hacked around with >> it a >> > bit since producing the numbers above, so it's now apparently a bit >> slower >> > than Aeson but allocates less too (~65kB). >> > >> > Could anyone help, e.g. by pointing me at the bit in the Core that is >> > allocating within the main loop? >> > >> While turning this over in my head I realized that this is the sort of >> program which may be helped significantly by GHC 8.2's improved join >> point handling. Indeed the timings seem to support this hypothesis: >> >> GHC 8.0.2 >> >> benchmarking json-validator/Automaton/testEvent >> time 22.84 μs (22.76 μs .. 22.94 μs) >> 1.000 R² (1.000 R² .. 1.000 R²) >> mean 22.84 μs (22.76 μs .. 22.94 μs) >> std dev 297.4 ns (221.8 ns .. 378.8 ns) >> >> Alloc rate 4,015,256,078,038 bytes per MUT second >> >> GHC 8.2 >> >> benchmarking json-validator/Automaton/testEvent >> time 9.221 μs (9.141 μs .. 9.318 μs) >> 0.998 R² (0.996 R² .. 1.000 R²) >> mean 9.163 μs (9.084 μs .. 9.356 μs) >> std dev 399.8 ns (193.0 ns .. 745.4 ns) >> variance introduced by outliers: 54% (severely inflated) >> >> Alloc rate 123,141,635 bytes per MUT second >> >> >> Wow! I suspect your allocations have now vanished. >> > > > Ooo, that's more like it. > > Could you run again using the following to get Criterion's estimate of the > allocations-per-call? > > json-validator-exe --regress allocated:iters +RTS -T >benchmarking json-validator/Automaton/testEvent Here it is, GHC 8.0.2 benchmarking json-validator/Automaton/testEvent time 34.81 μs (33.48 μs .. 36.10 μs) 0.991 R² (0.988 R² .. 0.994 R²) mean 34.04 μs (33.28 μs .. 34.99 μs) std dev 2.828 μs (2.423 μs .. 3.247 μs) allocated: 1.000 R² (1.000 R² .. 1.000 R²) iters 65924.651 (65895.364 .. 65951.510) y -4175.284 (-46736.295 .. 39814.235) variance introduced by outliers: 78% (severely inflated) GHC 8.2 benchmarking json-validator/Automaton/testEvent time 9.021 μs (8.923 μs .. 9.162 μs) 0.998 R² (0.994 R² .. 1.000 R²) mean 8.970 μs (8.905 μs .. 9.232 μs) std dev 341.4 ns (94.90 ns .. 711.7 ns) allocated: 0.973 R² (0.956 R² .. 0.984 R²) iters 343.033 (332.692 .. 354.606) y -7326.339 (-57269.638 .. 47222.231) variance introduced by outliers: 47% (moderately inflated) Cheers, - Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 487 bytes Desc: not available URL: From mikolaj at well-typed.com Fri May 12 13:26:52 2017 From: mikolaj at well-typed.com (Mikolaj Konarski) Date: Fri, 12 May 2017 15:26:52 +0200 Subject: [Haskell-cafe] Fast JSON validation - reducing allocations In-Reply-To: <874lwqgr0l.fsf@ben-laptop.smart-cactus.org> References: <87bmqzgru9.fsf@ben-laptop.smart-cactus.org> <874lwqgr0l.fsf@ben-laptop.smart-cactus.org> Message-ID: Truly impressive. Amazing. I wonder what style of coding of inner loops leads to such good results in 8.2. Is it easy to describe? Or is the answer "any" or "simplest" or "natural"? If not, can it be captured as some recursion combinators perhaps? >> json-validator-exe --regress allocated:iters +RTS -T > > Here it is, > > GHC 8.0.2 > > benchmarking json-validator/Automaton/testEvent > time 34.81 μs (33.48 μs .. 36.10 μs) > 0.991 R² (0.988 R² .. 0.994 R²) > mean 34.04 μs (33.28 μs .. 34.99 μs) > std dev 2.828 μs (2.423 μs .. 3.247 μs) > allocated: 1.000 R² (1.000 R² .. 1.000 R²) > iters 65924.651 (65895.364 .. 65951.510) > y -4175.284 (-46736.295 .. 39814.235) > variance introduced by outliers: 78% (severely inflated) > > > GHC 8.2 > > benchmarking json-validator/Automaton/testEvent > time 9.021 μs (8.923 μs .. 9.162 μs) > 0.998 R² (0.994 R² .. 1.000 R²) > mean 8.970 μs (8.905 μs .. 9.232 μs) > std dev 341.4 ns (94.90 ns .. 711.7 ns) > allocated: 0.973 R² (0.956 R² .. 0.984 R²) > iters 343.033 (332.692 .. 354.606) > y -7326.339 (-57269.638 .. 47222.231) > variance introduced by outliers: 47% (moderately inflated) From ben at well-typed.com Fri May 12 13:44:11 2017 From: ben at well-typed.com (Ben Gamari) Date: Fri, 12 May 2017 09:44:11 -0400 Subject: [Haskell-cafe] Fast JSON validation - reducing allocations In-Reply-To: References: <1494523609.3067104.973553536.32A155B5@webmail.messagingengine.com> <87k25ngtsp.fsf@ben-laptop.smart-cactus.org> <878tm3gpeu.fsf@ben-laptop.smart-cactus.org> <1494577660.20209.1.camel@gmail.com> Message-ID: <87zieifavo.fsf@ben-laptop.smart-cactus.org> David Turner writes: > On 12 May 2017 at 09:27, Arjen wrote: > >> >> Maybe this is a silly question, and please let me know why if so, but: >> >> Has anyone thought about parallelizing it for multiple messages in >> order to "produce garbage faster"? While reducing allocation will make >> the single validations faster, doing multiple ones might improve the >> throughput per GC ratio. This assumes that the amount of live data in >> the heap is small, making GC sort of constant time, and having multiple >> cores available. >> > > Not a silly question at all. Adding the following incantation: > > `using` parListChunk 100 rseq > > does quite happily spread things across all 4 cores on my development > machine, and it's certainly a bit faster. To give some stats, it processes > ~24 events between GCs rather than ~6, and collects ~2MB rather than > ~500kB. The throughput becomes a lot less consistent, however, at least > partly due to some bigger GC pauses along the way. As Ben's statistics > showed, our allocation rate on one thread is around 4TBps, which is already > stressing the GC out a bit, and parallelising it doesn't make that problem > any easier. > To elaborate on this a bit: in my experience allocation rate becomes even more important for performance (both latency and throughput) when introducing parallelism. The reason is that our GC is a stop-the-world collector and consequently whenever one thread needs to GC, it must stop and wait for all others to stop as well. This means that your program will be synchronizing constantly, even if your threads are working on completely non-intersecting sets of heap objects, greatly limiting your usable parallelism. You can observe this behavior using the eventlog. It is possible to tune the GC to trade latency for throughput without changing your program. Increasing the size of the nursery will mean that each thread will take longer to fill its nursery and consequently require less frequent GC. However, this means that each minor GC will take longer. For this reason, if your program is truly embarassingly parallel, it is usually preferrable performance-wise to run multiple processes concurrently than use pure parallelism (a sad truth in a harsh reality, in my opinion). Note that there have been efforts to help this issue in the past: Simon Marlow has a paper [1] examining a GC scheme with thread-local heaps, allowing threads to perform minor collections while other threads continue to run. Unfortunately this introduced a significant amount of complexity into the RTS which the performance numbers just didn't justify. The new compact regions feature also bears on this issue, as it gives users tools for better managing the effect of their long-lived live data on GC performance. That being said, this wouldn't help in your case as you have little long-lived live data. Some form of the linear types proposal also may some day offer some help here as it could in principle allow alternatives to today's GC'd heap. For instance, in your case you may want to use an arena allocation strategy: when starting a document allocate an arena which will serve as your nursery, run your computation, copy your result out to the GC'd heap at the end, and throw away the arena. Finally, I hope that someone will some day pick up the RTS work again. This might mean trying another approach to thread-local heaps, allowing multiple indepedent heaps per RTS, or even allowing multiple RTSs per process. It is sad that our parallelism story is limited in the ways that it is and there are still a number of stones that remain unturned. Cheers, - Ben [1] http://community.haskell.org/~simonmar/local-gc.pdf -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 487 bytes Desc: not available URL: From dct25-561bs at mythic-beasts.com Fri May 12 14:27:32 2017 From: dct25-561bs at mythic-beasts.com (David Turner) Date: Fri, 12 May 2017 15:27:32 +0100 Subject: [Haskell-cafe] Fast JSON validation - reducing allocations In-Reply-To: <87zieifavo.fsf@ben-laptop.smart-cactus.org> References: <1494523609.3067104.973553536.32A155B5@webmail.messagingengine.com> <87k25ngtsp.fsf@ben-laptop.smart-cactus.org> <878tm3gpeu.fsf@ben-laptop.smart-cactus.org> <1494577660.20209.1.camel@gmail.com> <87zieifavo.fsf@ben-laptop.smart-cactus.org> Message-ID: On 12 May 2017 at 14:44, Ben Gamari wrote: > > For this reason, if your program is truly embarassingly parallel, it is > usually preferrable performance-wise to run multiple processes > concurrently than use pure parallelism (a sad truth in a harsh reality, > in my opinion). > > Hmm, an interesting idea. It's not _all_ embarassingly parallel, but the bottleneck is. You're right, we could have separate front-end processes just doing the validation (indeed they could even be distributed across the network). I don't think we'll do that just yet, particularly not when 8.2's results are so promising, but it sounds a useful idea to keep in the toolbox. Thanks again, David -------------- next part -------------- An HTML attachment was scrubbed... URL: From ben at well-typed.com Fri May 12 15:32:19 2017 From: ben at well-typed.com (Ben Gamari) Date: Fri, 12 May 2017 11:32:19 -0400 Subject: [Haskell-cafe] Fast JSON validation - reducing allocations In-Reply-To: References: <1494523609.3067104.973553536.32A155B5@webmail.messagingengine.com> <87k25ngtsp.fsf@ben-laptop.smart-cactus.org> <878tm3gpeu.fsf@ben-laptop.smart-cactus.org> <1494577660.20209.1.camel@gmail.com> <87zieifavo.fsf@ben-laptop.smart-cactus.org> Message-ID: <87vap6f5vg.fsf@ben-laptop.smart-cactus.org> David Turner writes: > On 12 May 2017 at 14:44, Ben Gamari wrote: > >> >> For this reason, if your program is truly embarassingly parallel, it is >> usually preferrable performance-wise to run multiple processes >> concurrently than use pure parallelism (a sad truth in a harsh reality, >> in my opinion). >> >> > Hmm, an interesting idea. It's not _all_ embarassingly parallel, but the > bottleneck is. You're right, we could have separate front-end processes > just doing the validation (indeed they could even be distributed across the > network). I don't think we'll do that just yet, particularly not when 8.2's > results are so promising, but it sounds a useful idea to keep in the > toolbox. > Indeed. Note that Haskell is also quite good at distributed computation. StaticPointers makes it relatively easy to talk about code distributed across processes and machines. See, for instance, the Cloud Haskell suite of libraries. Cheers, - Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 487 bytes Desc: not available URL: From ben at smart-cactus.org Fri May 12 15:47:32 2017 From: ben at smart-cactus.org (Ben Gamari) Date: Fri, 12 May 2017 11:47:32 -0400 Subject: [Haskell-cafe] Fast JSON validation - reducing allocations In-Reply-To: References: <87bmqzgru9.fsf@ben-laptop.smart-cactus.org> <874lwqgr0l.fsf@ben-laptop.smart-cactus.org> Message-ID: <87shkaf563.fsf@ben-laptop.smart-cactus.org> Mikolaj Konarski writes: > Truly impressive. Amazing. > > I wonder what style of coding of inner loops > leads to such good results in 8.2. Is it easy to describe? > Or is the answer "any" or "simplest" or "natural"? If not, > can it be captured as some recursion combinators perhaps? > My fairly unhelpful description would be that carefully-written programs that look like they shouldn't allocate will be helped most. Previously these program (e.g. probably the one here) would allocate closures due to GHC's failure to identify some types of join points. In 8.2 our treatment of join points is more robust and consequently this unnecessary allocation will be more reliably eliminated. Cheers, - Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 487 bytes Desc: not available URL: From rae at cs.brynmawr.edu Fri May 12 17:22:35 2017 From: rae at cs.brynmawr.edu (Richard Eisenberg) Date: Fri, 12 May 2017 13:22:35 -0400 Subject: [Haskell-cafe] [ghc-proposals/cafe] Partially applied type families In-Reply-To: <59159295.24b.73e9.13590@clear.net.nz> References: <59159295.24b.73e9.13590@clear.net.nz> Message-ID: <8C84A927-864C-4C9C-BB5B-3D11E0775D57@cs.brynmawr.edu> > On May 12, 2017, at 6:46 AM, Anthony Clayden wrote: > > So please explain here in what way > type families are "half baked". My interpretation of mniip’s use of this descriptor was a reference to the fact that type families aren’t just functions, don’t support `case`, can’t be partially applied, etc. Instead, we should just be able to use functions in types. :) I agree that closed type families are bizarre and perhaps a misfeature -- though I think they are a good incremental step toward something better. What would be far better is if we could just use `case`, and then the closed type family syntax would desugar into case statements, much like how normal functions work. So type family F a b where F Int b = b F a Bool = a (AntC’s example) would really mean type F a b = case a of Int -> b _ -> case b of Bool -> a _ -> F a b We understand the semantics of case expressions, so this would avoid the bizarreness of closed type families. (We would also have to eliminate non-linear patterns, replacing them with some other first-class test for equality. It’s currently unclear to me how to do this right. Section 5.13.2 of my thesis dwells on this, without much in the way of a concrete way forward.) AntC’s proposed disequality constraints then become straightforward pattern guards. Richard From 14 at mniip.com Sat May 13 06:40:47 2017 From: 14 at mniip.com (mniip) Date: Sat, 13 May 2017 09:40:47 +0300 Subject: [Haskell-cafe] [ghc-proposals/cafe] Partially applied type families In-Reply-To: <8C84A927-864C-4C9C-BB5B-3D11E0775D57@cs.brynmawr.edu> References: <59159295.24b.73e9.13590@clear.net.nz> <8C84A927-864C-4C9C-BB5B-3D11E0775D57@cs.brynmawr.edu> Message-ID: <20170513064047.GA1549@mniip.com> On Fri, May 12, 2017 at 01:22:35PM -0400, Richard Eisenberg wrote: > > > On May 12, 2017, at 6:46 AM, Anthony Clayden wrote: > > > > So please explain here in what way > > type families are "half baked". > > My interpretation of mniip’s use of this descriptor was a reference to the fact that type families aren’t just functions, don’t support `case`, can’t be partially applied, etc. Instead, we should just be able to use functions in types. :) That is very much correct, but what I was exactly referring to was not the necessary limitations of type families (such as inability of partial application) but rather their unnecessary limitations. For example only being able to pattern-match at the top-level, or, with InjectiveTypeFamilies, lack of 'result arg1 -> arg2' type injectivity. > I agree that closed type families are bizarre and perhaps a misfeature -- though I think they are a good incremental step toward something better. Closed type families have proven very useful to me, so I don't agree with calling them a misfeature, however I can see where you're coming from : throughout the entire language we enforce the notion that we can't have a "proof of type inequality" and then closed type families give us just that. Indeed, their semantics could be made more apparent. From anthony_clayden at clear.net.nz Sat May 13 10:49:39 2017 From: anthony_clayden at clear.net.nz (Anthony Clayden) Date: Sat, 13 May 2017 22:49:39 +1200 Subject: [Haskell-cafe] [ghc-proposals/cafe] Partially applied type families Message-ID: <5916e4c3.122.1642.23109@clear.net.nz> > On Fri May 12 17:22:35 UTC 2017, Richard Eisenberg wrote: > > > On May 12, 2017, at 6:46 AM, Anthony Clayden wrote: > > So please explain here in what way > > type families are "half baked". > > My interpretation of mniip's use of this descriptor was > a reference to the fact that type families aren't just > functions, don't support `case`, ... ?? But the instance mechanism is in effect case; only considerably more powerful: > I agree that closed type families are bizarre and perhaps > a misfeature -- though I think they are a good incremental > step toward something better. What would be far better is > if we could just use `case`, and then the closed type > family syntax would desugar into case statements, much > like how normal functions work. So > > type family F a b where > F Int b = b > F a Bool = a > > (AntC's example) would really mean > > type F a b = case a of > Int -> b > _ -> case b of > Bool -> a > _ -> F a b > But this is terrible for type improvement!: It insists on working through the args left to right. And through the equations top to bottom. Contrast all the good work Richard did for closed families, to 'look ahead', detect confluence of equations, and try to make progress in solving equations. As described here https://typesandkinds.wordpress.com/2013/04/29/coincident-overlap-in-type-families/ and in the 2013 paper. i.e. to mimic the behaviour of stand-alone instances. > We understand the semantics of case expressions, ... At the term level yes. But that semantics is not appropriate at the type level. Type-level programming is somewhat like term level; but quite a lot different. At the term level, we never expect to 'improve' an argument from knowledge of the result. So expecting them to behave the same, or deliberately hobbling type improvement to be like term-level case expressions is just not ergonomic. What's so difficult to understand about instances? The worst mis-feature for me about closed families, is I have to put all the instances together, not alongside the corresponding class instances -- even as associated types. 'Grounding' type instances with methods, and therefore with class instances seems to be a Good Thing, according to these musings https://typesandkinds.wordpress.com/2015/09/09/what-are-type-families/ Closed families aren't extensible when I declare a new type. The part of the (class) instance mechanism that's difficult to reason about is overlaps. So the idea of the (dis)equality guards on instances -- which can apply to class or type instances -- is to remove overlaps: essentially, if the heads overlap (are unifiable), the guards must disambiguate which instance to choose. I can't introduce in a different module an instance that overlaps. AntC From tomandltimotej at gmail.com Sat May 13 10:53:31 2017 From: tomandltimotej at gmail.com (Timotej Tomandl) Date: Sat, 13 May 2017 11:53:31 +0100 Subject: [Haskell-cafe] natVal straight to Word# Message-ID: Hi, I am using type-level naturals constrained to be at max the size of Word#, as such I have found myself casting the type-level naturals first to Integer and then to Word# like this type MaxConstraint a=a<=MaxNat toNatural :: forall n. (MaxConstraint n,KnownNat n)=>Natural n toNatural = Natural (integerToWord (natVal (Proxy :: Proxy n))) where MaxNat is the hard-coded value of maxBound :: Word for now, type MaxNat=18446744073709551615 My data type and the constrained constructor for Natural are data Natural (x::Nat) where Natural :: (MaxConstraint x)=>{-# UNPACK #-} !Word# -> Natural x I have tried to eliminate the integerToWord cast from toNatural, yet I have failed at doing so. As such I would like to ask, if anyone has some insight, whether it is possible to eliminate this one step of indirection. The only option I came up with is writing GHC plugin to do this. Timo -------------- next part -------------- An HTML attachment was scrubbed... URL: From anthony_clayden at clear.net.nz Sat May 13 11:12:02 2017 From: anthony_clayden at clear.net.nz (Anthony Clayden) Date: Sat, 13 May 2017 23:12:02 +1200 Subject: [Haskell-cafe] [ghc-proposals/cafe] Partially applied type families Message-ID: <5916ea02.384.2f57.27034@clear.net.nz> > On Sat May 13 06:40:47 UTC 2017, mniip wrote3: >> On Fri, May 12, 2017 at 01:22:35PM -0400, Richard Eisenberg wrote: >> >> My interpretation of mniip’s use of this descriptor was .. > That is very much correct, but what I was exactly referring to was not > the necessary limitations of type families (such as inability of partial > application) but rather their unnecessary limitations. For example only > being able to pattern-match at the top-level, or, with > InjectiveTypeFamilies, lack of 'result arg1 -> arg2' type injectivity. Don't we get limited injectivity through type family calls appearing in Equality constraints? > class (F a b ~ c) => C a b c We might have: > type instance F Int b = b And a use site which gives (a ~ Int). Then we can improve via (b ~ c). >> I agree that closed type families are bizarre and perhaps a misfeature >> -- though I think they are a good incremental step toward something better. > Closed type families have proven very useful to me, ... Thanks mniip. Yes useful to me too. (As a major user of HList-alikes.) > so I don't agree with calling them a misfeature, ... I think there were plenty of people suggesting other ways to achieve the same end. If "something better" comes out of the experience, we've lost 7~8 years of opportunity. > however I can see where you're coming from : > throughout the entire language we enforce the notion that we > can't have a "proof of type inequality" and then > closed type families give us just that. I don't like calling it "type inequality". It's proof of non-unifiability. And the rules for that are easy to write down. (Admittedly a bit messy to apply in practice.) The key fact is that Oleg et al demonstrated how it worked way back in 2004. And it works in Hugs! I don't see what's so hard. > Indeed, their semantics could be made more apparent. Disequality guards make it blimmin obvious. As described in Sulzmann & Stuckey 2002. AntC From lysxia at gmail.com Sat May 13 12:44:12 2017 From: lysxia at gmail.com (Li-yao Xia) Date: Sat, 13 May 2017 08:44:12 -0400 Subject: [Haskell-cafe] natVal straight to Word# In-Reply-To: References: Message-ID: <0f5a5ef8-e37c-051d-a560-b2f94bf7dca1@gmail.com> Hi Timotej, A KnownNat constraint gets desugared into an Integer parameter by GHC, so it seems difficult to get rid of the conversion altogether. If you mimic the KnownNat type class, for Word instead of Integer: newtype Tagged n a = Tagged a class KnownWord n where word :: Tagged n Word then you can push out the Integer -> Word conversions to the boundaries of your application. I mean that internally, you need only to pass Words around, and your internal functions would look like: internalFunction :: (KnownWord n, KnownWord m) => ... But on the outside, you may still have to do a conversion. instance (KnownNat n, n <= MaxWord) => KnownWord n where word = Tagged (integerToWord (natVal (Proxy :: Proxy n))) externalFunction :: (KnownNat n, KnownNat m, n <= MaxWord, m <= MaxWord) => ... externalFunction = internalFunction There are also a few GHC-specific tricks to help work with such a type class without GHC plugins; the constraints[1] package gives some examples (in particular, see the Data.Constraint.Nat module); this involves unsafeCoerce. You can avoid Integer -> Word conversions by instead getting the Word from a runtime value. In particular, it is possible to write the following: someWord :: Word -> SomeWord -- or some variants, depending on the extensions available, specifically AllowAmbiguousTypes, TypeApplications, ScopedTypeVariables. data SomeWord where SomeWord :: KnownWord n => SomeWord You can also reflect type-level operations with operations on Word (as opposed to having to do everything with Integers first), and even provide tools for reasoning about these operations, all of that without getting out of the compiler, as opposed to plugins. plusWord :: (KnownWord n, KnownWord m) :- KnownWord (n + m) -- maybe with (n + m <= MaxWord) on the left hand side too As I mentioned earlier, this requires internal use of unsafeCoerce, but it is possible to keep it contained and expose a safe interface. Regards, Li-yao [1] http://hackage.haskell.org/package/constraints From vagarenko at gmail.com Sat May 13 16:01:42 2017 From: vagarenko at gmail.com (Alexey Vagarenko) Date: Sat, 13 May 2017 16:01:42 +0000 Subject: [Haskell-cafe] natVal straight to Word# In-Reply-To: <0f5a5ef8-e37c-051d-a560-b2f94bf7dca1@gmail.com> References: <0f5a5ef8-e37c-051d-a560-b2f94bf7dca1@gmail.com> Message-ID: I wonder what are the reasons for 'natVal' not having polymorphic type like 'natVal :: (KnownNat n, Num a) => proxy n -> a ? сб, 13 мая 2017 г. в 17:46, Li-yao Xia : > Hi Timotej, > > A KnownNat constraint gets desugared into an Integer parameter by GHC, > so it seems difficult to get rid of the conversion altogether. > > If you mimic the KnownNat type class, for Word instead of Integer: > > > newtype Tagged n a = Tagged a > > class KnownWord n where > word :: Tagged n Word > > > then you can push out the Integer -> Word conversions to the boundaries > of your application. I mean that internally, you need only to pass Words > around, and your internal functions would look like: > > > internalFunction :: (KnownWord n, KnownWord m) => ... > > > But on the outside, you may still have to do a conversion. > > > instance (KnownNat n, n <= MaxWord) => KnownWord n where > word = Tagged (integerToWord (natVal (Proxy :: Proxy n))) > > externalFunction :: (KnownNat n, KnownNat m, n <= MaxWord, m <= > MaxWord) => ... > externalFunction = internalFunction > > > There are also a few GHC-specific tricks to help work with such a type > class without GHC plugins; the constraints[1] package gives some > examples (in particular, see the Data.Constraint.Nat module); this > involves unsafeCoerce. You can avoid Integer -> Word conversions by > instead getting the Word from a runtime value. In particular, it is > possible to write the following: > > > someWord :: Word -> SomeWord > > -- or some variants, depending on the extensions available, > specifically AllowAmbiguousTypes, TypeApplications, ScopedTypeVariables. > data SomeWord where SomeWord :: KnownWord n => SomeWord > > > You can also reflect type-level operations with operations on Word (as > opposed to having to do everything with Integers first), and even > provide tools for reasoning about these operations, all of that without > getting out of the compiler, as opposed to plugins. > > > plusWord :: (KnownWord n, KnownWord m) :- KnownWord (n + m) -- > maybe with (n + m <= MaxWord) on the left hand side too > > > As I mentioned earlier, this requires internal use of unsafeCoerce, but > it is possible to keep it contained and expose a safe interface. > > Regards, > Li-yao > > [1] http://hackage.haskell.org/package/constraints > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From oleg.grenrus at iki.fi Sat May 13 16:29:06 2017 From: oleg.grenrus at iki.fi (Oleg Grenrus) Date: Sat, 13 May 2017 19:29:06 +0300 Subject: [Haskell-cafe] natVal straight to Word# In-Reply-To: References: Message-ID: FWIW. In GHC-8.2 the `natVal` from GHC.TypeNats (not TypeLits!) will return `Natural`. - Oleg On 13.05.2017 13:53, Timotej Tomandl wrote: > Hi, > I am using type-level naturals constrained to be at max the size of > Word#, as such I have found myself casting the type-level naturals > first to Integer and then to Word# like this > > type MaxConstraint a=a<=MaxNat > toNatural :: forall n. (MaxConstraint n,KnownNat n)=>Natural n > toNatural = Natural (integerToWord (natVal (Proxy :: Proxy n))) > > where MaxNat is the hard-coded value of maxBound :: Word for now, > > type MaxNat=18446744073709551615 > > My data type and the constrained constructor for Natural are > > data Natural (x::Nat) where > Natural :: (MaxConstraint x)=>{-# UNPACK #-} !Word# -> Natural x > > I have tried to eliminate the integerToWord cast from toNatural, yet I > have failed at doing so. > As such I would like to ask, if anyone has some insight, whether it is > possible to eliminate this one step of indirection. The only option I > came up with is writing GHC plugin to do this. > > Timo > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: From ramsaykeith at gmail.com Sun May 14 01:20:28 2017 From: ramsaykeith at gmail.com (Keith Ramsay) Date: Sat, 13 May 2017 19:20:28 -0600 Subject: [Haskell-cafe] Haskell-Cafe Digest, Vol 165, Issue 19 In-Reply-To: References: Message-ID: On 5/12/17, haskell-cafe-request at haskell.org wrote: > Send Haskell-Cafe mailing list submissions to > haskell-cafe at haskell.org > > To subscribe or unsubscribe via the World Wide Web, visit > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > or, via email, send a message with subject or body 'help' to > haskell-cafe-request at haskell.org > > You can reach the person managing the list at > haskell-cafe-owner at haskell.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Haskell-Cafe digest..." > > > Today's Topics: > > 1. Haskell IDE Engine users? (Alan & Kim Zimmerman) > 2. Fast JSON validation - reducing allocations (David Turner) > 3. Re: Fast JSON validation - reducing allocations (Bardur Arantsson) > 4. Re: Fast JSON validation - reducing allocations (David Turner) > 5. Re: Fast JSON validation - reducing allocations (Bardur Arantsson) > 6. Re: Fast JSON validation - reducing allocations (Eric Seidel) > 7. Re: Fast JSON validation - reducing allocations (Ben Gamari) > 8. Re: Fast JSON validation - reducing allocations (Ben Gamari) > 9. Re: Fast JSON validation - reducing allocations (David Turner) > 10. Re: Fast JSON validation - reducing allocations (Ben Gamari) > 11. Re: Fast JSON validation - reducing allocations (David Turner) > 12. Re: Fast JSON validation - reducing allocations (Arjen) > 13. Re: Fast JSON validation - reducing allocations (David Turner) > 14. Re: Fast JSON validation - reducing allocations (Arjen) > 15. Re: Fast JSON validation - reducing allocations (Arjen) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Thu, 11 May 2017 16:02:17 +0200 > From: "Alan & Kim Zimmerman" > To: haskell > Subject: [Haskell-cafe] Haskell IDE Engine users? > Message-ID: > > Content-Type: text/plain; charset="utf-8" > > Stupid question, but is anyone using/integrating HIE into anything at the > moment? > > I am considering rearranging the internals to orient it toward being mainly > a Language Server Protocol backend , and I want to see who would be > affected. > > Alan > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > > ------------------------------ > > Message: 2 > Date: Thu, 11 May 2017 17:12:15 +0100 > From: David Turner > To: Haskell Cafe > Subject: [Haskell-cafe] Fast JSON validation - reducing allocations > Message-ID: > > Content-Type: text/plain; charset="utf-8" > > Dear Café, > > We have a stream of ~900byte JSON documents (lazy ByteStrings) that we > would like to validate (NB not parse) as quickly as possible. We just need > to check that the bytes are a syntactically valid JSON document and then > pass them elsewhere; we do not care what the content is. The documents are > encoded in UTF-8 and have no extraneous whitespace. > > We have made a number of attempts: > > 1. Use Aeson to parse the documents and then discard the result. This was > actually pretty good: Criterion clocked it at ~30us per document. > > 2. A hand-written Attoparsec parser. This did quite a bit worse: ~70us per > document. > > 3. Use Get (from the binary package), which was a bit messier as it was > factored to avoid all backtracking, but managed to get down to around ~20us > per document. > > 4. Build a table-based, Word8-labelled DFA (with a minor hack to deal with > values-within-values) and run it with ByteString.Lazy.foldl'. Also around > ~20us per document. > > We didn't pursue the Attoparsec idea any further, but the other three all > allocate ~85kB per document, and this now seems to be the limiting factor > for performance. In more detail, looking at the threadscope output, we see > it parse 5 or 6 documents in ~150us (allocating ~500kB) and then run the > GC, which takes about another 150us. The GC stats indicate that it's only > copying a couple of kB of live data each time, so most of that 500kB is > junk. > > Now 85kB per document is ~96B per byte, which is only a pointer-and-a-half. > It's not entirely surprising that there's this much allocation going on > each time round the loop, but we'd like to try and get rid of it. I've > tried the usual strictness tricks and have peered in a mystified fashion at > the output of -ddump-simpl but am none the wiser. > > There's a copy of the relevant code for option 4 at > https://github.com/DaveCTurner/json-validator. I've hacked around with it a > bit since producing the numbers above, so it's now apparently a bit slower > than Aeson but allocates less too (~65kB). > > Could anyone help, e.g. by pointing me at the bit in the Core that is > allocating within the main loop? > > Many thanks, > > David > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > > ------------------------------ > > Message: 3 > Date: Thu, 11 May 2017 18:30:18 +0200 > From: Bardur Arantsson > To: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Fast JSON validation - reducing > allocations > Message-ID: > Content-Type: text/plain; charset=utf-8 > > On 2017-05-11 18:12, David Turner wrote: >> Dear Café, >> >> We have a stream of ~900byte JSON documents (lazy ByteStrings) that we >> would like to validate (NB not parse) as quickly as possible. We just >> need to check that the bytes are a syntactically valid JSON document and >> then pass them elsewhere; we do not care what the content is. The >> documents are encoded in UTF-8 and have no extraneous whitespace. >> > > No particular recommendations, but you might want to look into > semi-indexing[1] as a strategy. It looks plausible that it would be > possible to do that without a lot of allocation; see the paper for > details. (I there's also a demo implementation in Python on GH.) > > [1] http://www.di.unipi.it/~ottavian/files/semi_index_cikm.pdf > > > > ------------------------------ > > Message: 4 > Date: Thu, 11 May 2017 17:59:32 +0100 > From: David Turner > To: Haskell Cafe > Subject: Re: [Haskell-cafe] Fast JSON validation - reducing > allocations > Message-ID: > > Content-Type: text/plain; charset="utf-8" > > Interesting, thanks for the link. However we're trying to do _even less_ > than that - this is just the "scan the document to produce the Elias-Fano > encoding" step, except without needing to keep a hold of it for later. It's > not quite as trivial as that paper makes out as (a) it doesn't mention the > possibility that the documents might not be well-formed, and (b) it doesn't > really talk about dealing with the special delimiting characters within > string literals, for which you need to drag along a bunch of state while > you're scanning. > > This'd be pretty trivial to do in a C-like language now we've got the DFA > tables built, and I may resort to that at some point if we can't work out > how to avoid the allocations in Haskell-land, but I'd quite like to be able > to solve problems of this form without unnecessarily resorting to C. > > Cheers, > > On 11 May 2017 at 17:30, Bardur Arantsson wrote: > >> On 2017-05-11 18:12, David Turner wrote: >> > Dear Café, >> > >> > We have a stream of ~900byte JSON documents (lazy ByteStrings) that we >> > would like to validate (NB not parse) as quickly as possible. We just >> > need to check that the bytes are a syntactically valid JSON document and >> > then pass them elsewhere; we do not care what the content is. The >> > documents are encoded in UTF-8 and have no extraneous whitespace. >> > >> >> No particular recommendations, but you might want to look into >> semi-indexing[1] as a strategy. It looks plausible that it would be >> possible to do that without a lot of allocation; see the paper for >> details. (I there's also a demo implementation in Python on GH.) >> >> [1] http://www.di.unipi.it/~ottavian/files/semi_index_cikm.pdf >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > > ------------------------------ > > Message: 5 > Date: Thu, 11 May 2017 19:11:04 +0200 > From: Bardur Arantsson > To: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Fast JSON validation - reducing > allocations > Message-ID: > Content-Type: text/plain; charset=utf-8 > > On 2017-05-11 18:59, David Turner wrote: >> Interesting, thanks for the link. However we're trying to do _even less_ >> than that - this is just the "scan the document to produce the >> Elias-Fano encoding" step, except without needing to keep a hold of it >> for later. It's not quite as trivial as that paper makes out as (a) it >> doesn't mention the possibility that the documents might not be >> well-formed, and (b) it doesn't really talk about dealing with the >> special delimiting characters within string literals, for which you need >> to drag along a bunch of state while you're scanning. > > My thinking was actually that it could be used reduce the allocations > since everything (AFAIR, it's been a while) would basically just be > linear datastructures and indexes. > >> This'd be pretty trivial to do in a C-like language now we've got the >> DFA tables built, and I may resort to that at some point if we can't >> work out how to avoid the allocations in Haskell-land, but I'd quite >> like to be able to solve problems of this form without unnecessarily >> resorting to C. > > We'll there's always > > https://hackage.haskell.org/package/inline-c > > :) > > Regards, > > > > ------------------------------ > > Message: 6 > Date: Thu, 11 May 2017 10:26:49 -0700 > From: Eric Seidel > To: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Fast JSON validation - reducing > allocations > Message-ID: > <1494523609.3067104.973553536.32A155B5 at webmail.messagingengine.com> > Content-Type: text/plain; charset="utf-8" > > > On Thu, May 11, 2017, at 09:12, David Turner wrote: >> Could anyone help, e.g. by pointing me at the bit in the Core that is >> allocating within the main loop? > > GHC has a -ticky flag that tracks precisely where allocations are > happening. It's quite low level (you may have to stare at the STG in > addition to the Core to interpret the results) but I've found it > incredibly useful when trying to understand performance swings in GHC's > own benchmarks. > > https://ghc.haskell.org/trac/ghc/wiki/Debugging/TickyTicky > > You can enable it per module, which is nice break from the > rebuild-the-world -prof, but the flip side IIRC is that if the > allocations are happening in a module that wasn't compiled with -ticky > (e.g. somewhere inside Data.Array) you might not see them. > > Hope this helps! > Eric > > > ------------------------------ > > Message: 7 > Date: Thu, 11 May 2017 13:57:58 -0400 > From: Ben Gamari > To: David Turner > Cc: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Fast JSON validation - reducing > allocations > Message-ID: <87k25ngtsp.fsf at ben-laptop.smart-cactus.org> > Content-Type: text/plain; charset="utf-8" > > Eric Seidel writes: > >> On Thu, May 11, 2017, at 09:12, David Turner wrote: >>> Could anyone help, e.g. by pointing me at the bit in the Core that is >>> allocating within the main loop? >> >> GHC has a -ticky flag that tracks precisely where allocations are >> happening. It's quite low level (you may have to stare at the STG in >> addition to the Core to interpret the results) but I've found it >> incredibly useful when trying to understand performance swings in GHC's >> own benchmarks. >> >> https://ghc.haskell.org/trac/ghc/wiki/Debugging/TickyTicky >> >> You can enable it per module, which is nice break from the >> rebuild-the-world -prof, but the flip side IIRC is that if the >> allocations are happening in a module that wasn't compiled with -ticky >> (e.g. somewhere inside Data.Array) you might not see them. >> > Indeed, -ticky is wonderful for this sort of thing since it doesn't > affect Core-to-Core optimization, meaning that the instrumented program > will behave very similarly to the uninstrumented version (just a bit > slower due to counter overhead). > > I had a quick look at your example over lunch. I started like this > (after commenting out the aeson benchmark in Main), > > $ ghc app/Main.hs -isrc -O2 -ddump-stg -fforce-recomp \ > -ddump-to-file -dsuppress-idinfo -ddump-simpl -rtsopts \ > -ticky -ticky-allocd > $ app/Main +RTS -rticky.out > > This produces a Ticky report (named ticky.out) in the current directory. > This includes a table which in my case looked something like, > > Entries Alloc Alloc'd Non-void Arguments STG Name > > -------------------------------------------------------------------------------- > 123 192 48 1 L go9{v slyX} > (main at main:Automaton) > 2 0 32 1 L go8{v slyH} > (main at main:Automaton) > 1465016 58600640 146501600 0 $w$j1{v slMc} > (main at main:Automaton) in slHB > 161884268 011761148448 0 $w$j1{v slJT} > (main at main:Automaton) in slHA > 0 0 11720128 4 ppww $s$wgo2{v > slHz} (main at main:Automaton) in r4s > 16353241111790448768 13185144 5 wwLpp $wgo7{v slHA} > (main at main:Automaton) in r4s > 1831270 167011824 13185144 6 ppwLww $s$wgo1{v > slHB} (main at main:Automaton) in r4s > 183127 0 13185144 0 $w$j{v slGN} > (main at main:Automaton) in r4s > 992 8624 10944 1 L go7{v slwV} > (main at main:Automaton) in r4m > 3 72 0 1 C > main at main:Automaton.showGraph120{v r3O} > 681 0 0 2 ML go6{v rkSd} > (main at main:Automaton) > > The important things we care about here are Alloc (that is how many > bytes each name allocates) and Alloc'd (that is, how many of each > closure are allocated in bytes). [Aside: we explicitly enabled the > Alloc'd column during compilation with the -ticky-allocd flag; if you > omit it this column will contain only zeros. In general I find it > helpful to have so I generally enable it, despite the overhead it > introduces.] > > The table suggests a few nice starting points: $w$j1_slJT is allocated > quite a bit, probably by $wgo7_slHA. Next we can turn to the STG output > (src/Automaton.dump-stg) to try to understand why this is. Reading STG > generally tends to be quite hard due to the rather large, deeply nested > trees that most programs compile to. That being said, a good editor can > help immensely (I also have my ghc-dump [1] package which I've been > meaning to add STG support to, which would enable some interesting > analysis techniques). > > Unfortunately, my lunch is now all gone so I'll have to drop this here > for now. However, I'll try to pick it up again tonight. Do keep us > apprised of your progress! > > Cheers, > > - Ben > > > [1] https://github.com/bgamari/ghc-dump > -------------- next part -------------- > A non-text attachment was scrubbed... > Name: signature.asc > Type: application/pgp-signature > Size: 487 bytes > Desc: not available > URL: > > > ------------------------------ > > Message: 8 > Date: Thu, 11 May 2017 14:40:14 -0400 > From: Ben Gamari > To: David Turner , Haskell Cafe > > Cc: Luke Maurer > Subject: Re: [Haskell-cafe] Fast JSON validation - reducing > allocations > Message-ID: <87bmqzgru9.fsf at ben-laptop.smart-cactus.org> > Content-Type: text/plain; charset="utf-8" > > Ccing Luke Maurer under the assumption that he will appreciate seeing > the fruits of his labor. > > > David Turner writes: > >> Dear Café, >> > (snip) >> >> There's a copy of the relevant code for option 4 at >> https://github.com/DaveCTurner/json-validator. I've hacked around with it >> a >> bit since producing the numbers above, so it's now apparently a bit slower >> than Aeson but allocates less too (~65kB). >> >> Could anyone help, e.g. by pointing me at the bit in the Core that is >> allocating within the main loop? >> > While turning this over in my head I realized that this is the sort of > program which may be helped significantly by GHC 8.2's improved join > point handling. Indeed the timings seem to support this hypothesis: > > GHC 8.0.2 > > benchmarking json-validator/Automaton/testEvent > time 22.84 μs (22.76 μs .. 22.94 μs) > 1.000 R² (1.000 R² .. 1.000 R²) > mean 22.84 μs (22.76 μs .. 22.94 μs) > std dev 297.4 ns (221.8 ns .. 378.8 ns) > > Alloc rate 4,015,256,078,038 bytes per MUT second > > GHC 8.2 > > benchmarking json-validator/Automaton/testEvent > time 9.221 μs (9.141 μs .. 9.318 μs) > 0.998 R² (0.996 R² .. 1.000 R²) > mean 9.163 μs (9.084 μs .. 9.356 μs) > std dev 399.8 ns (193.0 ns .. 745.4 ns) > variance introduced by outliers: 54% (severely inflated) > > Alloc rate 123,141,635 bytes per MUT second > > > Wow! I suspect your allocations have now vanished. > > I didn't verify that the improvement really was due to more join points, > but it seems quite likely. Well done Luke! > > Cheers, > > - Ben > > -------------- next part -------------- > A non-text attachment was scrubbed... > Name: signature.asc > Type: application/pgp-signature > Size: 487 bytes > Desc: not available > URL: > > > ------------------------------ > > Message: 9 > Date: Thu, 11 May 2017 19:56:00 +0100 > From: David Turner > To: Haskell Cafe > Subject: Re: [Haskell-cafe] Fast JSON validation - reducing > allocations > Message-ID: > > Content-Type: text/plain; charset="utf-8" > > Ben, Eric, thanks for your help. A whole new world of low-level statistics > opens up before me... > > On 11 May 2017 at 18:57, Ben Gamari wrote: >> Eric Seidel writes: >> >> > On Thu, May 11, 2017, at 09:12, David Turner wrote: >> >> Could anyone help, e.g. by pointing me at the bit in the Core that is >> >> allocating within the main loop? >> > >> > GHC has a -ticky flag that tracks precisely where allocations are >> > happening. It's quite low level (you may have to stare at the STG in >> > addition to the Core to interpret the results) but I've found it >> > incredibly useful when trying to understand performance swings in GHC's >> > own benchmarks. >> > >> > https://ghc.haskell.org/trac/ghc/wiki/Debugging/TickyTicky >> > >> > You can enable it per module, which is nice break from the >> > rebuild-the-world -prof, but the flip side IIRC is that if the >> > allocations are happening in a module that wasn't compiled with -ticky >> > (e.g. somewhere inside Data.Array) you might not see them. >> >> Indeed, -ticky is wonderful for this sort of thing since it doesn't >> affect Core-to-Core optimization, meaning that the instrumented program >> will behave very similarly to the uninstrumented version (just a bit >> slower due to counter overhead). >> >> I had a quick look at your example over lunch. I started like this >> (after commenting out the aeson benchmark in Main), >> >> $ ghc app/Main.hs -isrc -O2 -ddump-stg -fforce-recomp \ >> -ddump-to-file -dsuppress-idinfo -ddump-simpl -rtsopts \ >> -ticky -ticky-allocd >> $ app/Main +RTS -rticky.out > > > Ok, I was just about to ask about the Alloc'd column as mine was all > zeroes, but the -ticky-allocd was what I needed, thanks. > >> The table suggests a few nice starting points: $w$j1_slJT is allocated >> quite a bit, probably by $wgo7_slHA. Next we can turn to the STG output >> (src/Automaton.dump-stg) to try to understand why this is. Reading STG >> generally tends to be quite hard due to the rather large, deeply nested >> trees that most programs compile to. > > You're not wrong. > > I've trawled through the STG as best as I can for a newbie. The function > with a large number in the 'Alloc' column looks pretty much to be the heart > of the `step` function. There's a lot of nesting but it looks largely to be > just checking the bounds on array indices, which I don't think allocates > anything. > > However I see this this little snippet at the very bottom of the nesting: > > case > indexArray# [ds1_sl1b > y2_sl5H] > of > _ [Occ=Dead] > { (##) ipv8_sl60 [Occ=Once!] -> > case > ipv8_sl60 > of > _ [Occ=Dead] > { GHC.Word.W8# dt6_sl62 [Occ=Once] -> > case > ss_sl5v > of > dt7_sl63 > { __DEFAULT -> > (#,,#) [__word 1 > dt6_sl62 > dt7_sl63]; > }; > }; > }; > > > I'm guessing that the `indexArray` call is the line that reads `nextState = > aTransitionsTable makeAutomaton AU.! (currentState, nextByte)`, and to me > it looks like it might be unboxing the thing it's getting out of the array. > Not sure that counts as an allocation, but I'm surprised anyway. > > I'll keep digging anyway, but it'd be good to hear of any progress at your > end too. Hope it didn't spoil your lunch! > > Cheers, > >> While turning this over in my head I realized that this is the sort of >> program which may be helped significantly by GHC 8.2's improved join >> point handling. Indeed the timings seem to support this hypothesis: >> >> GHC 8.0.2 >> >> benchmarking json-validator/Automaton/testEvent >> time 22.84 μs (22.76 μs .. 22.94 μs) >> 1.000 R² (1.000 R² .. 1.000 R²) >> mean 22.84 μs (22.76 μs .. 22.94 μs) >> std dev 297.4 ns (221.8 ns .. 378.8 ns) >> >> Alloc rate 4,015,256,078,038 bytes per MUT second >> >> GHC 8.2 >> >> benchmarking json-validator/Automaton/testEvent >> time 9.221 μs (9.141 μs .. 9.318 μs) >> 0.998 R² (0.996 R² .. 1.000 R²) >> mean 9.163 μs (9.084 μs .. 9.356 μs) >> std dev 399.8 ns (193.0 ns .. 745.4 ns) >> variance introduced by outliers: 54% (severely inflated) >> >> Alloc rate 123,141,635 bytes per MUT second >> >> >> Wow! I suspect your allocations have now vanished. > > Ooo, that's more like it. > > Could you run again using the following to get Criterion's estimate of the > allocations-per-call? > > json-validator-exe --regress allocated:iters +RTS -T > > Cheers, > > David > > On 11 May 2017 at 19:45, David Turner wrote: > >> On 11 May 2017 at 19:40, Ben Gamari wrote: >> >>> Ccing Luke Maurer under the assumption that he will appreciate seeing >>> the fruits of his labor. >>> >>> >>> David Turner writes: >>> >>> > Dear Café, >>> > >>> (snip) >>> > >>> > There's a copy of the relevant code for option 4 at >>> > https://github.com/DaveCTurner/json-validator. I've hacked around with >>> it a >>> > bit since producing the numbers above, so it's now apparently a bit >>> slower >>> > than Aeson but allocates less too (~65kB). >>> > >>> > Could anyone help, e.g. by pointing me at the bit in the Core that is >>> > allocating within the main loop? >>> > >>> While turning this over in my head I realized that this is the sort of >>> program which may be helped significantly by GHC 8.2's improved join >>> point handling. Indeed the timings seem to support this hypothesis: >>> >>> GHC 8.0.2 >>> >>> benchmarking json-validator/Automaton/testEvent >>> time 22.84 μs (22.76 μs .. 22.94 μs) >>> 1.000 R² (1.000 R² .. 1.000 R²) >>> mean 22.84 μs (22.76 μs .. 22.94 μs) >>> std dev 297.4 ns (221.8 ns .. 378.8 ns) >>> >>> Alloc rate 4,015,256,078,038 bytes per MUT second >>> >>> GHC 8.2 >>> >>> benchmarking json-validator/Automaton/testEvent >>> time 9.221 μs (9.141 μs .. 9.318 μs) >>> 0.998 R² (0.996 R² .. 1.000 R²) >>> mean 9.163 μs (9.084 μs .. 9.356 μs) >>> std dev 399.8 ns (193.0 ns .. 745.4 ns) >>> variance introduced by outliers: 54% (severely inflated) >>> >>> Alloc rate 123,141,635 bytes per MUT second >>> >>> >>> Wow! I suspect your allocations have now vanished. >>> >> >> >> Ooo, that's more like it. >> >> Could you run again using the following to get Criterion's estimate of the >> allocations-per-call? >> >> json-validator-exe --regress allocated:iters +RTS -T >> >> Cheers, >> >> David >> >> > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > > ------------------------------ > > Message: 10 > Date: Thu, 11 May 2017 15:32:41 -0400 > From: Ben Gamari > To: David Turner > Cc: Haskell Cafe > Subject: Re: [Haskell-cafe] Fast JSON validation - reducing > allocations > Message-ID: <878tm3gpeu.fsf at ben-laptop.smart-cactus.org> > Content-Type: text/plain; charset="utf-8" > > David Turner writes: > >> Ben, Eric, thanks for your help. A whole new world of low-level statistics >> opens up before me... >> > No worries! > >> You're not wrong. >> >> I've trawled through the STG as best as I can for a newbie. The function >> with a large number in the 'Alloc' column looks pretty much to be the >> heart >> of the `step` function. There's a lot of nesting but it looks largely to >> be >> just checking the bounds on array indices, which I don't think allocates >> anything. >> > Something that I should have mentioned earlier is that STG has the nice > property that all allocation is syntactically obvious: allocated > closures manifest as `let`s. This makes it fairly easy to pick out > possible allocation sites, even in large dumps. > >> However I see this this little snippet at the very bottom of the nesting: >> >> case >> indexArray# [ds1_sl1b >> y2_sl5H] >> of >> _ [Occ=Dead] >> { (##) ipv8_sl60 [Occ=Once!] -> >> case >> ipv8_sl60 >> of >> _ [Occ=Dead] >> { GHC.Word.W8# dt6_sl62 [Occ=Once] -> >> case >> ss_sl5v >> of >> dt7_sl63 >> { __DEFAULT -> >> (#,,#) [__word 1 >> dt6_sl62 >> dt7_sl63]; >> }; >> }; >> }; >> >> >> I'm guessing that the `indexArray` call is the line that reads `nextState >> = >> aTransitionsTable makeAutomaton AU.! (currentState, nextByte)`, and to me >> it looks like it might be unboxing the thing it's getting out of the >> array. >> Not sure that counts as an allocation, but I'm surprised anyway. >> > The unboxing should just involve looking at the value field of the W8# > closure (e.g. a memory dereference) and putting the value in a machine > register. There is no allocation here as far as I can see. > > >> I'll keep digging anyway, but it'd be good to hear of any progress at your >> end too. Hope it didn't spoil your lunch! > > Far from it! It was nice to have a puzzle to ponder. > > Cheers, > > - Ben > -------------- next part -------------- > A non-text attachment was scrubbed... > Name: signature.asc > Type: application/pgp-signature > Size: 487 bytes > Desc: not available > URL: > > > ------------------------------ > > Message: 11 > Date: Fri, 12 May 2017 09:10:50 +0100 > From: David Turner > To: Ben Gamari , Haskell Cafe > > Subject: Re: [Haskell-cafe] Fast JSON validation - reducing > allocations > Message-ID: > > Content-Type: text/plain; charset="utf-8" > > Morning all, > > On 11 May 2017 at 20:32, Ben Gamari wrote: > >> >> Something that I should have mentioned earlier is that STG has the nice >> property that all allocation is syntactically obvious: allocated >> closures manifest as `let`s. This makes it fairly easy to pick out >> possible allocation sites, even in large dumps. >> > > > Ah, that's very useful to know! > > Armed with that knowledge, I came to the conclusion that the allocation was > for the sharing of the `nextState` variable. Inlining it brings it down to > 20us and 22kB per iteration. > > https://github.com/DaveCTurner/json-validator/commit/ec994ec9226ca7bc2e76f19bef98f42e0b233524 > > Getting closer, but it looks like waiting for 8.2 is a better answer. > Looking forward to it! > > Cheers, > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > > ------------------------------ > > Message: 12 > Date: Fri, 12 May 2017 10:27:40 +0200 > From: Arjen > To: David Turner , Ben Gamari > , Haskell Cafe > Subject: Re: [Haskell-cafe] Fast JSON validation - reducing > allocations > Message-ID: <1494577660.20209.1.camel at gmail.com> > Content-Type: text/plain; charset="UTF-8" > > On Fri, 2017-05-12 at 09:10 +0100, David Turner wrote: >> Morning all, >> >> On 11 May 2017 at 20:32, Ben Gamari wrote: >> > Something that I should have mentioned earlier is that STG has the >> > nice >> > property that all allocation is syntactically obvious: allocated >> > closures manifest as `let`s. This makes it fairly easy to pick out >> > possible allocation sites, even in large dumps. >> >> >> Ah, that's very useful to know! >> >> Armed with that knowledge, I came to the conclusion that the >> allocation was for the sharing of the `nextState` variable. Inlining >> it brings it down to 20us and 22kB per iteration. >> >> https://github.com/DaveCTurner/json-validator/commit/ec994ec9226ca7bc >> 2e76f19bef98f42e0b233524 >> >> Getting closer, but it looks like waiting for 8.2 is a better answer. >> Looking forward to it! >> >> Cheers, >> > > Maybe this is a silly question, and please let me know why if so, but: > > Has anyone thought about parallelizing it for multiple messages in > order to "produce garbage faster"? While reducing allocation will make > the single validations faster, doing multiple ones might improve the > throughput per GC ratio. This assumes that the amount of live data in > the heap is small, making GC sort of constant time, and having multiple > cores available. > > I wonder whether a few strategically placed par's and pseq's might > allow you to scale horizontally without requiring invasive changes to > the program's structure. Apologies for not trying to do this myself > first ;-). > > kind regards, Arjen > > > ------------------------------ > > Message: 13 > Date: Fri, 12 May 2017 10:48:01 +0100 > From: David Turner > To: Arjen , Haskell Cafe > > Subject: Re: [Haskell-cafe] Fast JSON validation - reducing > allocations > Message-ID: > > Content-Type: text/plain; charset="utf-8" > > On 12 May 2017 at 09:27, Arjen wrote: > >> >> Maybe this is a silly question, and please let me know why if so, but: >> >> Has anyone thought about parallelizing it for multiple messages in >> order to "produce garbage faster"? While reducing allocation will make >> the single validations faster, doing multiple ones might improve the >> throughput per GC ratio. This assumes that the amount of live data in >> the heap is small, making GC sort of constant time, and having multiple >> cores available. >> > > Not a silly question at all. Adding the following incantation: > > `using` parListChunk 100 rseq > > does quite happily spread things across all 4 cores on my development > machine, and it's certainly a bit faster. To give some stats, it processes > ~24 events between GCs rather than ~6, and collects ~2MB rather than > ~500kB. The throughput becomes a lot less consistent, however, at least > partly due to some bigger GC pauses along the way. As Ben's statistics > showed, our allocation rate on one thread is around 4TBps, which is already > stressing the GC out a bit, and parallelising it doesn't make that problem > any easier. > > I know in the OP I said "we have a stream" (accidental MLK misquote) but in > fact there are a bunch of parallel streams whose number exceeds the number > of available cores, so we don't anticipate any enormous benefit from > spreading the processing of any one stream across multiple cores: > single-threaded performance is what we think we should be concentrating on. > > Cheers, > > David > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > > ------------------------------ > > Message: 14 > Date: Fri, 12 May 2017 11:52:04 +0200 > From: Arjen > To: David Turner , Ben Gamari > , Haskell Cafe > Subject: Re: [Haskell-cafe] Fast JSON validation - reducing > allocations > Message-ID: <1494582724.20209.3.camel at gmail.com> > Content-Type: text/plain; charset="UTF-8" > > On Fri, 2017-05-12 at 10:27 +0200, Arjen wrote: >> On Fri, 2017-05-12 at 09:10 +0100, David Turner wrote: >> > Morning all, >> > >> > On 11 May 2017 at 20:32, Ben Gamari wrote: >> > > Something that I should have mentioned earlier is that STG has >> the >> > > nice >> > > property that all allocation is syntactically obvious: allocated >> > > closures manifest as `let`s. This makes it fairly easy to pick >> out >> > > possible allocation sites, even in large dumps. >> > >> > >> > Ah, that's very useful to know! >> > >> > Armed with that knowledge, I came to the conclusion that the >> > allocation was for the sharing of the `nextState` variable. >> Inlining >> > it brings it down to 20us and 22kB per iteration. >> > >> > https://github.com/DaveCTurner/json-validator/commit/ec994ec9226ca7 >> bc >> > 2e76f19bef98f42e0b233524 >> > >> > Getting closer, but it looks like waiting for 8.2 is a better >> answer. >> > Looking forward to it! >> > >> > Cheers, >> > >> >> Maybe this is a silly question, and please let me know why if so, >> but: >> >> Has anyone thought about parallelizing it for multiple messages in >> order to "produce garbage faster"? While reducing allocation will >> make >> the single validations faster, doing multiple ones might improve the >> throughput per GC ratio. This assumes that the amount of live data in >> the heap is small, making GC sort of constant time, and having >> multiple >> cores available. >> >> I wonder whether a few strategically placed par's and pseq's might >> allow you to scale horizontally without requiring invasive changes to >> the program's structure. Apologies for not trying to do this myself >> first ;-). >> > > Unfortunately, this does not seem to help. I tried it and while I did > see 3.5 and 3.95 CPU's used with parList and parListChunk 8, the > timings show it to be slower than sequential evaluation of a list of > testEvent. Thank you for the problem to try this on :-) > > Please let me know if I made a mistake in the testing code below. > > kind regards, Arjen > > ---8<--- > > benchmarking json-validator/Automaton/testEvent > time                 26.57 μs   (26.07 μs .. 27.12 μs) >                      0.987 R²   (0.973 R² .. 0.995 R²) > mean                 31.01 μs   (28.17 μs .. 44.49 μs) > std dev              15.65 μs   (5.258 μs .. 35.77 μs) > variance introduced by outliers: 99% (severely inflated) > > benchmarking json-validator/Automaton-List/testEventList > time                 65.11 ms   (61.54 ms .. 69.54 ms) >                      0.982 R²   (0.951 R² .. 0.996 R²) > mean                 59.18 ms   (56.28 ms .. 63.22 ms) > std dev              5.801 ms   (4.344 ms .. 8.238 ms) > variance introduced by outliers: 32% (moderately inflated) > > benchmarking json-validator/Automaton-ParList/testEventList > time                 243.9 ms   (214.9 ms .. 270.6 ms) >                      0.996 R²   (0.986 R² .. 1.000 R²) > mean                 253.7 ms   (243.6 ms .. 260.8 ms) > std dev              10.32 ms   (6.781 ms .. 13.19 ms) > variance introduced by outliers: 16% (moderately inflated) > > benchmarking json-validator/Automaton-ParListChunk/testEventList > time                 211.4 ms   (193.1 ms .. 232.3 ms) >                      0.997 R²   (0.990 R² .. 1.000 R²) > mean                 200.3 ms   (193.0 ms .. 206.6 ms) > std dev              9.256 ms   (7.106 ms .. 10.21 ms) > variance introduced by outliers: 14% (moderately inflated) > >   19,225,632,224 bytes allocated in the heap >      109,968,376 bytes copied during GC >        2,062,736 bytes maximum residency (20 sample(s)) >        2,250,352 bytes maximum slop >               10 MB total memory in use (0 MB lost due to > fragmentation) > >                                      Tot time (elapsed)  Avg pause  Max > pause >   Gen  0     28722 colls, 28722 > par   17.829s   1.591s     0.0001s    0.0160s >   Gen  1        20 colls,    19 > par    0.255s   0.054s     0.0027s    0.0058s > >   Parallel GC work balance: 7.41% (serial 0%, perfect 100%) > >   TASKS: 13 (1 bound, 12 peak workers (12 total), using -N4) > >   SPARKS: 25625 (25570 converted, 0 overflowed, 0 dud, 20 GC'd, 35 > fizzled) > >   INIT    time    0.001s  (  0.002s elapsed) >   MUT     time   44.403s  ( 22.013s elapsed) >   GC      time   18.084s  (  1.645s elapsed) >   EXIT    time    0.001s  (  0.001s elapsed) >   Total   time   62.490s  ( 23.660s elapsed) > >   Alloc rate    432,981,654 bytes per MUT second > >   Productivity  71.1% of total user, 93.0% of total elapsed > > gc_alloc_block_sync: 25370 > whitehole_spin: 0 > gen[0].sync: 405 > gen[1].sync: 22 > > ---8<--- > > {-# LANGUAGE OverloadedStrings #-} > > module Main where > > import           Criterion.Main > import           Data.Aeson > import qualified Data.ByteString.Lazy as BL > import qualified Data.Text.Encoding   as T > import qualified Data.Text.IO as T > import qualified Data.Text as T (append, pack) > import qualified Automaton > import Control.Parallel.Strategies > > testEvent :: Int -> BL.ByteString > testEvent i = BL.fromStrict $ T.encodeUtf8 (T.append > "{\"stream\":\"actuals- > stream\",\"submitter\":{\"type\":\"other\",\"description\":\"redactedre > dac\"},\"driverActivities\":[{\"driverActivity\":{\"journey\":{\"headco > de\":\"1A01\",\"description\":\"redactedredactedredactedredactedredacte > dredacte\"},\"activity\":[{\"arrivalTime\":null,\"sequence\":1,\"tiploc > \":\"REDACTE\",\"stop\":true,\"departureTime\":\"2016-06- > 09T18:22:28.000000000000Z\"},{\"arrivalTime\":\"2016-06- > 09T18:24:43.000000000000Z\",\"sequence\":2,\"tiploc\":\"REDACTE\",\"sto > p\":true,\"departureTime\":\"2016-06- > 09T18:25:51.000000000000Z\"},{\"arrivalTime\":\"2016-06- > 09T18:26:58.000000000000Z\",\"sequence\":3,\"tiploc\":\"REDACT\",\"stop > \":true,\"departureTime\":\"2016-06- > 09T18:28:08.000000000000Z\"},{\"arrivalTime\":\"2016-06- > 09T18:29:57.000000000000Z\",\"sequence\":4,\"tiploc\":\"REDACTE\",\"sto > p\":true,\"departureTime\":null}]},\"activityUserId\":\"521be60a-02f2- > 4892-b468-c17d9c1c4fcf\"}],\"submissionTime\":\"2016-06- > 09T18:36:45.831486000000Z\",\"type\":\"driverActivityLogged" (T.append > (T.pack (show i)) "\"}")) > > data AnyJSON = AnyJSON >   deriving (Show, Eq) > > instance FromJSON AnyJSON where >   parseJSON _ = pure AnyJSON > > main :: IO () > main = print (testEventList [0]) >> defaultMain >   [ bgroup "json-validator/Automaton" >     [ bench "testEvent" $ whnf Automaton.isValidJson (testEvent 0) >     ] >   , bgroup "json-validator/Automaton-List" >     [ bench "testEventList" $ whnf (\es -> and (testEventList es > `using` rseq)) [1..1000] >     ] >   , bgroup "json-validator/Automaton-ParList" >     [ bench "testEventList" $ whnf (\es -> and (testEventList es > `using` parList rseq)) [1..1000] >     ] >   , bgroup "json-validator/Automaton-ParListChunk" >     [ bench "testEventList" $ whnf (\es -> and (testEventList es > `using` parListChunk 8 rseq)) [1..1000] >     ] >   ] >   where >     testEventList = map (Automaton.isValidJson . testEvent) > > > > ------------------------------ > > Message: 15 > Date: Fri, 12 May 2017 12:00:02 +0200 > From: Arjen > To: David Turner , Haskell Cafe > > Subject: Re: [Haskell-cafe] Fast JSON validation - reducing > allocations > Message-ID: <1494583202.20209.5.camel at gmail.com> > Content-Type: text/plain; charset="UTF-8" > > On Fri, 2017-05-12 at 10:48 +0100, David Turner wrote: >> On 12 May 2017 at 09:27, Arjen wrote: >> > Maybe this is a silly question, and please let me know why if so, >> > but: >> > >> > Has anyone thought about parallelizing it for multiple messages in >> > order to "produce garbage faster"? While reducing allocation will >> > make >> > the single validations faster, doing multiple ones might improve >> > the >> > throughput per GC ratio. This assumes that the amount of live data >> > in >> > the heap is small, making GC sort of constant time, and having >> > multiple >> > cores available. >> >> Not a silly question at all. Adding the following incantation: >> >>     `using` parListChunk 100 rseq >> >> does quite happily spread things across all 4 cores on my development >> machine, and it's certainly a bit faster. To give some stats, it >> processes ~24 events between GCs rather than ~6, and collects ~2MB >> rather than ~500kB. The throughput becomes a lot less consistent, >> however, at least partly due to some bigger GC pauses along the way. >> As Ben's statistics showed, our allocation rate on one thread is >> around 4TBps, which is already stressing the GC out a bit, and >> parallelising it doesn't make that problem any easier. >> >> I know in the OP I said "we have a stream" (accidental MLK misquote) >> but in fact there are a bunch of parallel streams whose number >> exceeds the number of available cores, so we don't anticipate any >> enormous benefit from spreading the processing of any one stream >> across multiple cores: single-threaded performance is what we think >> we should be concentrating on. >> >> Cheers, >> >> David >> > Happy to read that you have more success than I with parListChunk. > I expect(ed) the sparks to be cheap, so this might help if the various > incoming streams are very unbalanced in length and/or message sizes. > I agree that multi-processing a single stream does not make much sense > if you already have multiple concurrent streams. > > Nice to see that adding on parallelism in Haskell (GHC) is that easy > (in this case) and with a very good speed-up factor! > > kind regards, Arjen > > > ------------------------------ > > Subject: Digest Footer > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > > ------------------------------ > > End of Haskell-Cafe Digest, Vol 165, Issue 19 > ********************************************* > From jeffbrown.the at gmail.com Sun May 14 06:53:19 2017 From: jeffbrown.the at gmail.com (Jeffrey Brown) Date: Sat, 13 May 2017 23:53:19 -0700 Subject: [Haskell-cafe] Why is Megaparsec treating these two operators differently? In-Reply-To: References: Message-ID: The problem's not solved! Check out this weirdness. |+| and |-| are supposed to be identical, mapping to the same function, the Pair constructor. > mapM_ putStrLn exprs a |+| b a |-| b a |+| b |-| c a |-| b |+| c a |+| b |-| c |+| d > mapM_ putStrLn $ map (show . parseMaybe aExpr) exprs Just (Pair (Var "a") (Var "b")) Nothing Just (Pair (Pair (Var "a") (Var "b")) (Var "c")) Nothing Just (Pair (Pair (Var "a") (Var "b")) (Pair (Var "c") (Var "d"))) Why the two failures? If I change them from InfixN to InfixR or InfixL, then only the first of those five expressions parses. Here are two relevant definitions: data AExpr = Var String | Pair AExpr AExpr deriving (Show) aOperators :: [[Operator Parser AExpr]] aOperators = [ [ InfixN $ symbol "|+|" *> pure (Pair) ] , [ InfixN $ symbol "|-|" *> pure (Pair) ] -- binds last, I think ] And here is the code in full[1]. Thanks, Jeff [1] https://github.com/JeffreyBenjaminBrown/digraphs-with-text/blob/master/howto/megaparsec/minimal.hs On Sun, Oct 23, 2016 at 2:50 PM, Brandon Allbery wrote: > Aha. I had forgotten some details. > > If you want to have an operator that is a prefix of another operator in >> the table, use the following (or similar) wrapper instead of plain symbol >> : >> op n = (lexeme . try) (string n <* notFollowedBy punctuationChar) > > http://hackage.haskell.org/package/megaparsec-5.1.1/docs/ > Text-Megaparsec-Expr.html#v:makeExprParser > > So you actually need to be a little clever for those two operators to > work; it's not as simple as I had recalled it (which would have been > correct for a basic manual combinator setup). I am going to guess that > something in there is not using `try` and silently consuming the extra "#", > but I'd have to study the `makeExprParser` code in Megaparsec to be certain. > > On Sun, Oct 23, 2016 at 5:38 PM, Jeffrey Brown > wrote: > >> Thanks, Brandon! How did you know that? >> >> I changed them to "#1" and "#2" and now it works[1]. >> >> But before making that change, why would "a # b ## c # d" evaluate, even >> though "a ## b" would not? >> >> >> [1] https://github.com/JeffreyBenjaminBrown/digraphs-with-text/ >> tree/master/howto/megaparsec >> The corrected file is called "experim.hs"; the old one, uncorrected, is >> called "experim.buggy.hs". >> >> On Sun, Oct 23, 2016 at 2:03 PM, Brandon Allbery >> wrote: >> >>> >>> On Sun, Oct 23, 2016 at 4:15 PM, Jeffrey Brown >>> wrote: >>> >>>> [ [ InfixN # symbol "#" *> pure (Pair) ] >>>> , [ InfixN # symbol "##" *> pure (Pair) ] >>>> ] >>>> >>> >>> Combinator parsers can't rearrange themselves to do longest token >>> matching. So the ## operator will take the first case, match against >>> `symbol "#"` and aOperator will succeed; the the next token match will hit >>> the unconsumed "#" and fail. If you place "##" first then it will match >>> "##" but not "#", which would the match the second rule. >>> >>> -- >>> brandon s allbery kf8nh sine nomine >>> associates >>> allbery.b at gmail.com >>> ballbery at sinenomine.net >>> unix, openafs, kerberos, infrastructure, xmonad >>> http://sinenomine.net >>> >> >> >> >> -- >> Jeff Brown | Jeffrey Benjamin Brown >> Website | Facebook >> | LinkedIn >> (I often miss messages >> here) | Github >> > > > > -- > brandon s allbery kf8nh sine nomine > associates > allbery.b at gmail.com > ballbery at sinenomine.net > unix, openafs, kerberos, infrastructure, xmonad > http://sinenomine.net > -- Jeff Brown | Jeffrey Benjamin Brown Website | Facebook | LinkedIn (spammy, so I often miss messages here) | Github -------------- next part -------------- An HTML attachment was scrubbed... URL: From dct25-561bs at mythic-beasts.com Sun May 14 07:13:02 2017 From: dct25-561bs at mythic-beasts.com (David Turner) Date: Sun, 14 May 2017 08:13:02 +0100 Subject: [Haskell-cafe] Why is Megaparsec treating these two operators differently? In-Reply-To: References: Message-ID: The "code in full" link has operators called `#1` and `#2` rather than `|+|` and `|-|`, but I see one of your test cases fail there too. You're using quite an old version of megaparsec, 4.3.0 (stackage lts-5.5) and it looks like something affecting this was fixed in 4.4.0 (e.g. stackage lts-6.9): $ stack --resolver lts-5.5 ghci --no-load --no-build Configuring GHCi with the following packages: Dwt GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help Prelude> :l howto/megaparsec/minimal.hs [1 of 1] Compiling Experim ( howto/megaparsec/minimal.hs, interpreted ) Ok, modules loaded: Experim. *Experim> test Just (Pair (Var "a") (Var "b")) Nothing Just (Pair (Pair (Var "a") (Var "b")) (Pair (Var "c") (Var "d"))) Just (Pair (Pair (Var "a") (Var "b")) (Pair (Var "c") (Var "d"))) *Experim> Leaving GHCi. $ stack --resolver lts-6.9 ghci --no-load --no-build Configuring GHCi with the following packages: Dwt GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help Prelude> :l howto/megaparsec/minimal.hs [1 of 1] Compiling Experim ( howto/megaparsec/minimal.hs, interpreted ) Ok, modules loaded: Experim. *Experim> test Just (Pair (Var "a") (Var "b")) Just (Pair (Var "a") (Var "b")) Just (Pair (Pair (Var "a") (Var "b")) (Pair (Var "c") (Var "d"))) Just (Pair (Pair (Var "a") (Var "b")) (Pair (Var "c") (Var "d"))) *Experim> Leaving GHCi. On 14 May 2017 at 07:53, Jeffrey Brown wrote: > The problem's not solved! Check out this weirdness. |+| and |-| are > supposed to be identical, mapping to the same function, the Pair > constructor. > > > mapM_ putStrLn exprs > a |+| b > a |-| b > a |+| b |-| c > a |-| b |+| c > a |+| b |-| c |+| d > > mapM_ putStrLn $ map (show . parseMaybe aExpr) exprs > Just (Pair (Var "a") (Var "b")) > Nothing > Just (Pair (Pair (Var "a") (Var "b")) (Var "c")) > Nothing > Just (Pair (Pair (Var "a") (Var "b")) (Pair (Var "c") (Var "d"))) > > Why the two failures? > > If I change them from InfixN to InfixR or InfixL, then only the first of > those five expressions parses. > > Here are two relevant definitions: > > data AExpr = Var String | Pair AExpr AExpr deriving (Show) > > aOperators :: [[Operator Parser AExpr]] > aOperators = > [ [ InfixN $ symbol "|+|" *> pure (Pair) ] > , [ InfixN $ symbol "|-|" *> pure (Pair) ] -- binds last, I think > ] > > And here is the code in full[1]. > > Thanks, > Jeff > > > [1] https://github.com/JeffreyBenjaminBrown/digraphs- > with-text/blob/master/howto/megaparsec/minimal.hs > > > On Sun, Oct 23, 2016 at 2:50 PM, Brandon Allbery > wrote: > >> Aha. I had forgotten some details. >> >> If you want to have an operator that is a prefix of another operator in >>> the table, use the following (or similar) wrapper instead of plain >>> symbol: >>> op n = (lexeme . try) (string n <* notFollowedBy punctuationChar) >> >> http://hackage.haskell.org/package/megaparsec-5.1.1/docs/Tex >> t-Megaparsec-Expr.html#v:makeExprParser >> >> So you actually need to be a little clever for those two operators to >> work; it's not as simple as I had recalled it (which would have been >> correct for a basic manual combinator setup). I am going to guess that >> something in there is not using `try` and silently consuming the extra "#", >> but I'd have to study the `makeExprParser` code in Megaparsec to be certain. >> >> On Sun, Oct 23, 2016 at 5:38 PM, Jeffrey Brown >> wrote: >> >>> Thanks, Brandon! How did you know that? >>> >>> I changed them to "#1" and "#2" and now it works[1]. >>> >>> But before making that change, why would "a # b ## c # d" evaluate, even >>> though "a ## b" would not? >>> >>> >>> [1] https://github.com/JeffreyBenjaminBrown/digraphs-with-text/t >>> ree/master/howto/megaparsec >>> The corrected file is called "experim.hs"; the old one, uncorrected, is >>> called "experim.buggy.hs". >>> >>> On Sun, Oct 23, 2016 at 2:03 PM, Brandon Allbery >>> wrote: >>> >>>> >>>> On Sun, Oct 23, 2016 at 4:15 PM, Jeffrey Brown >>> > wrote: >>>> >>>>> [ [ InfixN # symbol "#" *> pure (Pair) ] >>>>> , [ InfixN # symbol "##" *> pure (Pair) ] >>>>> ] >>>>> >>>> >>>> Combinator parsers can't rearrange themselves to do longest token >>>> matching. So the ## operator will take the first case, match against >>>> `symbol "#"` and aOperator will succeed; the the next token match will hit >>>> the unconsumed "#" and fail. If you place "##" first then it will match >>>> "##" but not "#", which would the match the second rule. >>>> >>>> -- >>>> brandon s allbery kf8nh sine nomine >>>> associates >>>> allbery.b at gmail.com >>>> ballbery at sinenomine.net >>>> unix, openafs, kerberos, infrastructure, xmonad >>>> http://sinenomine.net >>>> >>> >>> >>> >>> -- >>> Jeff Brown | Jeffrey Benjamin Brown >>> Website | Facebook >>> | LinkedIn >>> (I often miss >>> messages here) | Github >>> >> >> >> >> -- >> brandon s allbery kf8nh sine nomine >> associates >> allbery.b at gmail.com >> ballbery at sinenomine.net >> unix, openafs, kerberos, infrastructure, xmonad >> http://sinenomine.net >> > > > > -- > Jeff Brown | Jeffrey Benjamin Brown > Website | Facebook > | LinkedIn > (spammy, so I often > miss messages here) | Github > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jeffbrown.the at gmail.com Sun May 14 07:38:48 2017 From: jeffbrown.the at gmail.com (Jeffrey Brown) Date: Sun, 14 May 2017 00:38:48 -0700 Subject: [Haskell-cafe] Why is Megaparsec treating these two operators differently? In-Reply-To: References: Message-ID: Awww yiss! Thanks, David! On Sun, May 14, 2017 at 12:13 AM, David Turner < dct25-561bs at mythic-beasts.com> wrote: > The "code in full" link has operators called `#1` and `#2` rather than > `|+|` and `|-|`, but I see one of your test cases fail there too. You're > using quite an old version of megaparsec, 4.3.0 (stackage lts-5.5) and it > looks like something affecting this was fixed in 4.4.0 (e.g. stackage > lts-6.9): > > $ stack --resolver lts-5.5 ghci --no-load --no-build > Configuring GHCi with the following packages: Dwt > GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help > Prelude> :l howto/megaparsec/minimal.hs > [1 of 1] Compiling Experim ( howto/megaparsec/minimal.hs, > interpreted ) > Ok, modules loaded: Experim. > *Experim> test > Just (Pair (Var "a") (Var "b")) > Nothing > Just (Pair (Pair (Var "a") (Var "b")) (Pair (Var "c") (Var "d"))) > Just (Pair (Pair (Var "a") (Var "b")) (Pair (Var "c") (Var "d"))) > *Experim> > Leaving GHCi. > $ stack --resolver lts-6.9 ghci --no-load --no-build > Configuring GHCi with the following packages: Dwt > GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help > Prelude> :l howto/megaparsec/minimal.hs > [1 of 1] Compiling Experim ( howto/megaparsec/minimal.hs, > interpreted ) > Ok, modules loaded: Experim. > *Experim> test > Just (Pair (Var "a") (Var "b")) > Just (Pair (Var "a") (Var "b")) > Just (Pair (Pair (Var "a") (Var "b")) (Pair (Var "c") (Var "d"))) > Just (Pair (Pair (Var "a") (Var "b")) (Pair (Var "c") (Var "d"))) > *Experim> > Leaving GHCi. > > > On 14 May 2017 at 07:53, Jeffrey Brown wrote: > >> The problem's not solved! Check out this weirdness. |+| and |-| are >> supposed to be identical, mapping to the same function, the Pair >> constructor. >> >> > mapM_ putStrLn exprs >> a |+| b >> a |-| b >> a |+| b |-| c >> a |-| b |+| c >> a |+| b |-| c |+| d >> > mapM_ putStrLn $ map (show . parseMaybe aExpr) exprs >> Just (Pair (Var "a") (Var "b")) >> Nothing >> Just (Pair (Pair (Var "a") (Var "b")) (Var "c")) >> Nothing >> Just (Pair (Pair (Var "a") (Var "b")) (Pair (Var "c") (Var "d"))) >> >> Why the two failures? >> >> If I change them from InfixN to InfixR or InfixL, then only the first of >> those five expressions parses. >> >> Here are two relevant definitions: >> >> data AExpr = Var String | Pair AExpr AExpr deriving (Show) >> >> aOperators :: [[Operator Parser AExpr]] >> aOperators = >> [ [ InfixN $ symbol "|+|" *> pure (Pair) ] >> , [ InfixN $ symbol "|-|" *> pure (Pair) ] -- binds last, I think >> ] >> >> And here is the code in full[1]. >> >> Thanks, >> Jeff >> >> >> [1] https://github.com/JeffreyBenjaminBrown/digraphs-with-text/ >> blob/master/howto/megaparsec/minimal.hs >> >> >> On Sun, Oct 23, 2016 at 2:50 PM, Brandon Allbery >> wrote: >> >>> Aha. I had forgotten some details. >>> >>> If you want to have an operator that is a prefix of another operator in >>>> the table, use the following (or similar) wrapper instead of plain >>>> symbol: >>>> op n = (lexeme . try) (string n <* notFollowedBy punctuationChar) >>> >>> http://hackage.haskell.org/package/megaparsec-5.1.1/docs/Tex >>> t-Megaparsec-Expr.html#v:makeExprParser >>> >>> So you actually need to be a little clever for those two operators to >>> work; it's not as simple as I had recalled it (which would have been >>> correct for a basic manual combinator setup). I am going to guess that >>> something in there is not using `try` and silently consuming the extra "#", >>> but I'd have to study the `makeExprParser` code in Megaparsec to be certain. >>> >>> On Sun, Oct 23, 2016 at 5:38 PM, Jeffrey Brown >>> wrote: >>> >>>> Thanks, Brandon! How did you know that? >>>> >>>> I changed them to "#1" and "#2" and now it works[1]. >>>> >>>> But before making that change, why would "a # b ## c # d" evaluate, >>>> even though "a ## b" would not? >>>> >>>> >>>> [1] https://github.com/JeffreyBenjaminBrown/digraphs-with-text/t >>>> ree/master/howto/megaparsec >>>> The corrected file is called "experim.hs"; the old one, uncorrected, is >>>> called "experim.buggy.hs". >>>> >>>> On Sun, Oct 23, 2016 at 2:03 PM, Brandon Allbery >>>> wrote: >>>> >>>>> >>>>> On Sun, Oct 23, 2016 at 4:15 PM, Jeffrey Brown < >>>>> jeffbrown.the at gmail.com> wrote: >>>>> >>>>>> [ [ InfixN # symbol "#" *> pure (Pair) ] >>>>>> , [ InfixN # symbol "##" *> pure (Pair) ] >>>>>> ] >>>>>> >>>>> >>>>> Combinator parsers can't rearrange themselves to do longest token >>>>> matching. So the ## operator will take the first case, match against >>>>> `symbol "#"` and aOperator will succeed; the the next token match will hit >>>>> the unconsumed "#" and fail. If you place "##" first then it will match >>>>> "##" but not "#", which would the match the second rule. >>>>> >>>>> -- >>>>> brandon s allbery kf8nh sine nomine >>>>> associates >>>>> allbery.b at gmail.com >>>>> ballbery at sinenomine.net >>>>> unix, openafs, kerberos, infrastructure, xmonad >>>>> http://sinenomine.net >>>>> >>>> >>>> >>>> >>>> -- >>>> Jeff Brown | Jeffrey Benjamin Brown >>>> Website | Facebook >>>> | LinkedIn >>>> (I often miss >>>> messages here) | Github >>>> >>> >>> >>> >>> -- >>> brandon s allbery kf8nh sine nomine >>> associates >>> allbery.b at gmail.com >>> ballbery at sinenomine.net >>> unix, openafs, kerberos, infrastructure, xmonad >>> http://sinenomine.net >>> >> >> >> >> -- >> Jeff Brown | Jeffrey Benjamin Brown >> Website | Facebook >> | LinkedIn >> (spammy, so I often >> miss messages here) | Github >> >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. >> > > -- Jeff Brown | Jeffrey Benjamin Brown Website | Facebook | LinkedIn (spammy, so I often miss messages here) | Github -------------- next part -------------- An HTML attachment was scrubbed... URL: From anthony_clayden at clear.net.nz Sun May 14 09:51:51 2017 From: anthony_clayden at clear.net.nz (Anthony Clayden) Date: Sun, 14 May 2017 21:51:51 +1200 Subject: [Haskell-cafe] [ghc-proposals/cafe] Partially applied type families Message-ID: <591828b7.2ae.37e1.16443@clear.net.nz> > On Fri May 12 17:22:35 UTC 2017, Richard Eisenberg wrote: > > ... [in] closed type families. (We > would also have to eliminate non-linear patterns, > replacing them with some other first-class test for > equality. > AntC's proposed disequality constraints then become > straightforward pattern guards. Guards don't have to be just disequalities. If you want to eliminate non-linear patterns, use _equality_ guards. Full example: > type family F a b where > F a a = a > F Int b = b > F a Bool = a > Translates to: > type instance F a b | a ~ b = a > type instance F a b | a ~ Int, a /~ b = b > type instance F a b | b ~ Bool, a /~ Int, a /~ b = a (Each instance after the first has disequality guards to negate the earlier instances' equalities., i.e. the earlier instances 'shadow' the overlap.) > It's currently unclear to me how to do this > right. ... > Assuming we have a primitive type-level equality test (?~), returning type-level Bool; we can use helper functions. The first instance desugars to a call > ... = F_a_b_Eq (a ?~ b) a b > type instance F_a_b_Eq True a b = a (Needs UndecidableInstances.) > Section 5.13.2 of my thesis dwells on this, without > much in the way of a concrete way forward.) We use type equality testing all the time. In fact instance selection relies on it. 5.13.2 says: "they [equality testing rules] cannot handle the case where Equals a a reduces to True, where a is locally bound type variable." ?? I thought GHC's equality test requires types to be grounded, i.e. not merely type vars, in order to be judged equal. Or did that change recently? Isn't that to do with impredicativity and the dreaded monomorphism: the same typevar might get a different forall-qualified type in different use sites. Contrast types can be judged dis-equal without necessarily being grounded. [HList paper section 9 refers.] AntC From ruben.astud at gmail.com Sun May 14 17:40:01 2017 From: ruben.astud at gmail.com (Ruben Astudillo) Date: Sun, 14 May 2017 13:40:01 -0400 Subject: [Haskell-cafe] eta-expansion and cost of extra thunk on ghc Message-ID: <8eaf5a23-32f6-4aa9-13f2-c715cb8ba359@gmail.com> Dear list On a class, we recently discussed the join function for a (State s) value (we where implementation Monad passing through Functor) join :: State s (State s a) -> State s a join outstate = State $ \s0 -> let (innerstate, s1) = runState outstate s0 in runState innerstate s1 On this, we eta-expand outstate to in a sense "pattern match" on what we know about it. We were thinking on the cost of the extra wrapping we do here for this "pattern matching". Because eta-expanding is one a of the 3 primitive operations on lambda calculus, we concluded it should be free (modulo presence of seq). Is this true on ghc? -- -- Ruben From jclites at mac.com Mon May 15 05:36:39 2017 From: jclites at mac.com (Jeff Clites) Date: Sun, 14 May 2017 22:36:39 -0700 Subject: [Haskell-cafe] eta-expansion and cost of extra thunk on ghc In-Reply-To: <8eaf5a23-32f6-4aa9-13f2-c715cb8ba359@gmail.com> References: <8eaf5a23-32f6-4aa9-13f2-c715cb8ba359@gmail.com> Message-ID: I don't think it's always free; I believe you'll incur the cost at least of allocating the closure to capture outstate in that lambda in the canonical case. But, if you are thinking of the code: runState (join x) y then it's likely that GHC will inline away everything such that it's free, but not so in the case in which you (say) store the result of join in some data structure and run it elsewhere. So I'd say whether it's free depends on exactly what code you are comparing it to, and I think it's a question of whether GHC has the opportunity to inline everything, not a direct consequence of the similarity to a lambda calculus primitive; that doesn't inherently make anything free. JEff > On May 14, 2017, at 10:40 AM, Ruben Astudillo wrote: > > Dear list > > On a class, we recently discussed the join function for a (State s) > value (we where implementation Monad passing through Functor) > > join :: State s (State s a) -> State s a > join outstate = > State $ \s0 -> > let (innerstate, s1) = runState outstate s0 > in runState innerstate s1 > > On this, we eta-expand outstate to in a sense "pattern match" on what we > know about it. We were thinking on the cost of the extra wrapping we do > here for this "pattern matching". Because eta-expanding is one a of the > 3 primitive operations on lambda calculus, we concluded it should be > free (modulo presence of seq). Is this true on ghc? > > -- > -- Ruben > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From rae at cs.brynmawr.edu Mon May 15 16:20:09 2017 From: rae at cs.brynmawr.edu (Richard Eisenberg) Date: Mon, 15 May 2017 12:20:09 -0400 Subject: [Haskell-cafe] [ghc-proposals/cafe] Partially applied type families In-Reply-To: <591828b7.2ae.37e1.16443@clear.net.nz> References: <591828b7.2ae.37e1.16443@clear.net.nz> Message-ID: Lots to respond to! I do think think there's one overarching question/theme here: Do we want functional dependencies or type-level functions? Behind AntC's arguments, I see a thrust toward functional dependencies. (Not necessarily their *syntax*, but the idea of type improvement and flexible -- that is, multidirectional -- type-level reasoning.) My dependent types work pushes me toward type-level functions. But I think we can have our cake and eat it too. See my recent draft paper (expanding on the "What are type families" blog post) here: http://cs.brynmawr.edu/~rae/papers/2017/partiality/partiality.pdf (This paper will appear in revised form at ICFP'17.) While the paper skirts around the issue somewhat, it's really proposing dropping type families in favor of functional dependencies -- but only for partial type families. The key observation is this: partiality in types is bizarre, and we don't want it. So, any time we use a partial type family, you need to have a class constraint around. The class constraint ensures that we evaluate the type family only within its defined domain. Now tied to classes, partial type families are more like convenient syntax for functional dependencies. There is also treatment of partial closed type families via a new construct, closed classes (somewhat like instance chains but weaker). I expect AntC would prefer disequality guards over closed classes. I would be interested to hear more from the community on this choice -- they're really the same as ordered equations under the hood, and it's just a choice of syntax. Maybe we can even have both. Now, on to individual points: > But this is terrible for type improvement!: I agree that desugaring to `case` expressions would harm type improvement. But it gives us a reliable semantics for type-level computation, something that is sorely lacking today. Can we reconcile these? Perhaps, but it will take some Hard Thought. In any case, any real implementation of these ideas would require the Hard Thought in order to be backward compatible. (This backward compatibility necessity is one of the reasons I love working with Haskell. When adding a feature to the language, we just can't take easy ways out!) > Closed families aren't extensible > when I declare a new type. Quite true, but it's easy enough to make an open type family that calls a closed type family. In the design of closed type families, we originally thought to have (what I called) branched instances, separating out the "closedness" with the overlapping equations. In the end, it seemed simpler to have closed families have the overlapping equations and dispense with branches instances. The big problem with branched instances is that it was awkward to describe the overlap between two branched instances. AntC might argue that, if we just had disequality guards, it would all be much simpler. He might be right. In retrospect, it would have been nice to have the proposals process active when designing closed type families; we might have come up with a better design. >> so I don't agree with calling [closed type families] a misfeature, ... > > I think there were plenty of people > suggesting other ways to achieve the same end. > If "something better" comes out of the experience, > we've lost 7~8 years of opportunity. By "misfeature", I didn't mean that I shouldn't have added closed type families. I'm more referring to some of the oddities pointed out in my draft paper linked above. My recollection at the time is that other approaches were more functional-dependency-like in character. (To wit: instance chains.) When I did the closed type family work, I was thinking that type families were better than functional dependencies; now, my view is much more nuanced (leaning strongly toward fundeps instead of partial type families). I'm not sure what you mean by "lost 7~8 years of opportunity". > I don't like calling it "type inequality". > It's proof of non-unifiability. I call it apartness! > I don't see what's so hard [about non-unifiability]. It's not nearly as hard from a fundep point of view. That's because there's a very key difference in fundep-land. Suppose we have > type family F a where > F Int = Bool and that's it. We can still use `F Char` in a type, even though it's nonsensical. Similarly, if a type family doesn't terminate, we can use the type family at a type that causes it to loop. If we translate the type families to fundeps, these problems go away (say, to `class C a b | a -> b; instance C Int Bool`), because a function with a type that mentions `C Char a` can never be called, as there is no `C Char xyz` instance. The key mistake behind the closed type families paper is, essentially, to assume that `F Char` is a type; all the apartness gobbledegook follows. In my draft paper, we reverse this assumption, cleaning up this theory quite nicely. > 5.13.2 says: "they [equality testing rules] cannot handle > the case where Equals a a reduces to True, > where a is locally bound type variable." > > ?? I thought GHC's equality test > requires types to be grounded, > i.e. not merely type vars, > in order to be judged equal. > Or did that change recently? No change here -- since the advent of closed type families, GHC has been able to reduce equality over non-ground types. That's the trouble. > Isn't that to do with impredicativity > and the dreaded monomorphism: > the same typevar might get a different > forall-qualified type in different use sites. Not sure what you're talking about here. GHC is resolutely predicative (in this manner, at least -- a logician would be highly flummoxed that we call a system with Type :: Type predicative!). I do have to say all this talk has made me think more about apartness constraints in FC, at least. They might be a touch simpler than the current story. Richard > On May 14, 2017, at 5:51 AM, Anthony Clayden wrote: > >> On Fri May 12 17:22:35 UTC 2017, Richard Eisenberg wrote: > >> >> ... [in] closed type families. (We >> would also have to eliminate non-linear patterns, >> replacing them with some other first-class test for >> equality. > >> AntC's proposed disequality constraints then become >> straightforward pattern guards. > > Guards don't have to be just disequalities. > > If you want to eliminate non-linear patterns, > use _equality_ guards. Full example: > >> type family F a b where >> F a a = a >> F Int b = b >> F a Bool = a >> > > Translates to: > >> type instance F a b | a ~ b = a >> type instance F a b | a ~ Int, a /~ b = b >> type instance F a b | b ~ Bool, a /~ Int, a /~ b = a > > (Each instance after the first > has disequality guards to negate the earlier instances' > equalities., i.e. the earlier instances 'shadow' the > overlap.) > >> It's currently unclear to me how to do this >> right. ... >> > > Assuming we have a primitive type-level > equality test (?~), returning type-level Bool; > we can use helper functions. > The first instance desugars to a call > >> ... = F_a_b_Eq (a ?~ b) a b > >> type instance F_a_b_Eq True a b = a > > (Needs UndecidableInstances.) > >> Section 5.13.2 of my thesis dwells on this, without >> much in the way of a concrete way forward.) > > We use type equality testing all the time. > In fact instance selection relies on it. > > 5.13.2 says: "they [equality testing rules] cannot handle > the case where Equals a a reduces to True, > where a is locally bound type variable." > > ?? I thought GHC's equality test > requires types to be grounded, > i.e. not merely type vars, > in order to be judged equal. > Or did that change recently? > > Isn't that to do with impredicativity > and the dreaded monomorphism: > the same typevar might get a different > forall-qualified type in different use sites. > > Contrast types can be judged dis-equal > without necessarily being grounded. > [HList paper section 9 refers.] > > > AntC From rae at cs.brynmawr.edu Mon May 15 17:15:25 2017 From: rae at cs.brynmawr.edu (Richard Eisenberg) Date: Mon, 15 May 2017 13:15:25 -0400 Subject: [Haskell-cafe] Partially applied type families In-Reply-To: References: Message-ID: > On May 12, 2017, at 8:31 AM, Soham Chowdhury wrote: > > Relatedly, there is a sketch of something like a "case construct" on Richard's blog, where he talks about a "type instance where" syntax that allows closed interdependent sets of family instances. Is that something that was later found to be infeasible? The `type instance where` construct has evolved to become closed type families. The expressiveness you see there still exists, but the syntax has evolved. Richard From zohl at fmap.me Mon May 15 21:09:14 2017 From: zohl at fmap.me (Al Zohali) Date: Tue, 16 May 2017 00:09:14 +0300 Subject: [Haskell-cafe] Position of a constraint in a function's signature Message-ID: <591A18FA.2020109@fmap.me> Dear Cafe! I've encountered quite strange behaviour in GHC (v8.0.2) and I would like to ask you to give me a hint. Suppose we have the following functions: ---- foo :: (Show a) => Int -> a -> [String] foo n = replicate n . show bar :: Int -> (Show a) => a -> [String] bar n = replicate n . show baz :: Int -> a -> (Show a) => [String] baz n = replicate n . show ---- This won't compile, and that is ok. But if we add `RankNTypes` extension, this will compile and (:t) will give us the same signature for all three functions. There are two things I cannot get: 1) Why do this even compile? I saw constraints being defined either in the beginning of a signature or right after `forall` expression. I thought that it was a rule (or convention), but it's not. Is this way of declaring constraints (in the middle of a signature) discouraged or can be considered as a bug? 2) Even if this was supposed to be so, why was the constraint in `baz` hoisted to the top? There are at least two ways to interpret that signature: ---- baz :: Int -> a -> forall a. (Show a) => [String] baz :: forall a. (Show a) => Int -> a -> [String] ---- Is there any reason why the second one was chosen? From allbery.b at gmail.com Mon May 15 21:16:55 2017 From: allbery.b at gmail.com (Brandon Allbery) Date: Mon, 15 May 2017 17:16:55 -0400 Subject: [Haskell-cafe] Position of a constraint in a function's signature In-Reply-To: <591A18FA.2020109@fmap.me> References: <591A18FA.2020109@fmap.me> Message-ID: There's a number of weirdnesses currently that basically fall out of the fact that the kinds Constraint and * are treated identically internally. See https://ghc.haskell.org/trac/ghc/ticket/11715 and stay tuned; it's not going to be fixed for 8.2 but probably will for 8.4 --- unless more bugs come crawling out of the woodwork, as has been happening a lot if you look at the ticket history. :) On Mon, May 15, 2017 at 5:09 PM, Al Zohali wrote: > Dear Cafe! > > I've encountered quite strange behaviour in GHC (v8.0.2) and I would > like to ask you to give me a hint. > > Suppose we have the following functions: > ---- > foo :: (Show a) => Int -> a -> [String] > foo n = replicate n . show > > bar :: Int -> (Show a) => a -> [String] > bar n = replicate n . show > > baz :: Int -> a -> (Show a) => [String] > baz n = replicate n . show > ---- > > This won't compile, and that is ok. But if we add `RankNTypes` > extension, this will compile and (:t) will give us the same signature > for all three functions. > > There are two things I cannot get: > > 1) Why do this even compile? > I saw constraints being defined either in the beginning of a signature > or right after `forall` expression. I thought that it was a rule (or > convention), but it's not. Is this way of declaring constraints (in > the middle of a signature) discouraged or can be considered as a bug? > > 2) Even if this was supposed to be so, why was the constraint in `baz` > hoisted to the top? > There are at least two ways to interpret that signature: > ---- > baz :: Int -> a -> forall a. (Show a) => [String] > baz :: forall a. (Show a) => Int -> a -> [String] > ---- > Is there any reason why the second one was chosen? > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -- brandon s allbery kf8nh sine nomine associates allbery.b at gmail.com ballbery at sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net -------------- next part -------------- An HTML attachment was scrubbed... URL: From will.yager at gmail.com Mon May 15 22:55:30 2017 From: will.yager at gmail.com (William Yager) Date: Mon, 15 May 2017 17:55:30 -0500 Subject: [Haskell-cafe] Position of a constraint in a function's signature In-Reply-To: <591A18FA.2020109@fmap.me> References: <591A18FA.2020109@fmap.me> Message-ID: Disclaimer: My understanding of this may be out of date/incomplete. My understanding of Haskell typing is largely based on https://web.cecs.pdx.edu/~mpj/thih/thih.pdf which is old and doesn't contain RankNTypes. 1) Why wouldn't it compile? "C => T" means (or is equivalent to) "A function which takes an implicit parameter C and returns a T". There's no particular reason this can't show up on the RHS of a "->" arrow. Admittedly, no one really uses typeclasses in this way, but it's not fundamentally wrong. 2) I don't believe the former interpretation of baz is valid. The "a" on its own and the one in "Show a" ought to be unified. When you quantify an unquantified type, you do it over the *entire* type, not just the variables that show up in constraints. There's no reason you would insert a "forall" in the RHS of an arrow. --Will On Mon, May 15, 2017 at 4:09 PM, Al Zohali wrote: > Dear Cafe! > > I've encountered quite strange behaviour in GHC (v8.0.2) and I would > like to ask you to give me a hint. > > Suppose we have the following functions: > ---- > foo :: (Show a) => Int -> a -> [String] > foo n = replicate n . show > > bar :: Int -> (Show a) => a -> [String] > bar n = replicate n . show > > baz :: Int -> a -> (Show a) => [String] > baz n = replicate n . show > ---- > > This won't compile, and that is ok. But if we add `RankNTypes` > extension, this will compile and (:t) will give us the same signature > for all three functions. > > There are two things I cannot get: > > 1) Why do this even compile? > I saw constraints being defined either in the beginning of a signature > or right after `forall` expression. I thought that it was a rule (or > convention), but it's not. Is this way of declaring constraints (in > the middle of a signature) discouraged or can be considered as a bug? > > 2) Even if this was supposed to be so, why was the constraint in `baz` > hoisted to the top? > There are at least two ways to interpret that signature: > ---- > baz :: Int -> a -> forall a. (Show a) => [String] > baz :: forall a. (Show a) => Int -> a -> [String] > ---- > Is there any reason why the second one was chosen? > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From allbery.b at gmail.com Tue May 16 00:47:17 2017 From: allbery.b at gmail.com (Brandon Allbery) Date: Mon, 15 May 2017 20:47:17 -0400 Subject: [Haskell-cafe] Position of a constraint in a function's signature In-Reply-To: References: <591A18FA.2020109@fmap.me> Message-ID: On Mon, May 15, 2017 at 6:55 PM, William Yager wrote: > "C => T" means (or is equivalent to) "A function which takes an implicit > parameter C and returns a T". There's no particular reason this can't show > up on the RHS of a "->" arrow. The Report requires that all constraints be in a tuple before the rest of a signature. ghc relaxes this since it implements not Haskell 2010, but System FC. But yes, this is why it's syntactically correct once you enable any extension that liberalizes type signature parsing. (Even without, ghc permits constraint => constraint ... => type for reasons that iirc are hard to "fix" and are not really considered bugs, just not Haskell 2010 syntax; but ghc's Haskell 2010 support broke when Num lost Eq and Show superclasses, and broke further when Monad gained Applicative prerequisite/"superclass", so nobody's much worried about the Report violation.) -- brandon s allbery kf8nh sine nomine associates allbery.b at gmail.com ballbery at sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net -------------- next part -------------- An HTML attachment was scrubbed... URL: From anthony_clayden at clear.net.nz Tue May 16 01:26:00 2017 From: anthony_clayden at clear.net.nz (Anthony Clayden) Date: Tue, 16 May 2017 13:26:00 +1200 Subject: [Haskell-cafe] [ghc-proposals/cafe] Partially applied type families Message-ID: <591a5528.271.3b05.31512@clear.net.nz> > On Mon May 15 16:20:09 UTC 2017, Richard Eisenberg wrote: > Lots to respond to! > Thanks Richard, phew! yes. Let's break it down a bit. > I do think think there's one overarching question/theme > here: Do we want functional dependencies or type-level > functions? Behind AntC's arguments, I see a thrust toward > functional dependencies. (Not necessarily their *syntax*, > but the idea of type improvement and flexible -- that is, > multidirectional -- type-level reasoning.) My dependent > types work pushes me toward type-level functions. Yes there is an overarching question. I don't think it's specifically FunDeps vs Type Functions. (Although I disagree the **Functional** Dependencies are somehow not "functional". Yes Mark Jones got the idea from Relational database theory. Where did Ted Codd get the idea from? Mathematical (binary) "relations", which are a set-theoretic account of, um, functions.) "Multidirectional type-level reasoning" is what all functional languages do: from Robinson's unification to Hindley-Milner to OutsideIn(X) to System F-subscript-superscript. There's been an example in Haskell's Prelude since ~1991: the `read` method's return type is 'demand-pulled' from context, not 'supply-pushed' from its parameter. Similarly if I write: > x :: Int > x = a + (b * c) We infer a, b, c must all be Int. Perhaps in another universe, Haskell had explicit type application from day 1, and insisted on giving type signatures for all vars (like nearly all procedural/OO languages). But we aren't in that universe, and I love Haskell/FP for being both type-safe and not pernickety in that way. > ... [big snip - I'll reply separately] > > I expect AntC would prefer disequality guards > over closed classes. Oh yes! I was about to say (repeating my earlier message): if we're going to ground type family instances in classes, then we need a way to distribute type instances as associated types, unless ... you're going to suggest something daft like closed classes. And then you did. > I would be interested to hear more from the > community on this choice -- they're really the same as > ordered equations under the hood, and it's just a choice > of syntax. Maybe we can even have both. > Yes please all chip in. There were strong views expressed 5~8 years ago. My two-penn'orth: I think we can mechanically translate closed equations to guards (equality and 'apart' tests). The example in my earlier post tried to show how. For class instances (with overlaps), I think there's also a mechanical translation, but only for 'well-behaved' sets of instances. (For Incoherent sets we don't have a chance.) And of course as soon as some imported instance overlaps, we have to start again to assess well-behavedness. > Now, on to individual points: > > ...the Hard Thought in order to be > backward compatible. (This backward compatibility > necessity is one of the reasons I love working with > Haskell. When adding a feature to the language, we just > can't take easy ways out!) > The backwards-compatibility I particularly want to preserve is "distributed instances". That is, putting the instance code close to type decls and other functions that build or consume that type. I also want to put explicitly *in the instance decl* the restraints on what types that instance applies for. Not implicit from where it appears in a closed but lengthy/voluminous sequence of equations. Yes there must be global coherence for the class/type instances. That's a mechanical check which compilers are good at, but humans not so much. > ... it was awkward to describe the overlap between two > branched instances. AntC might argue that, if we just had > disequality guards, it would all be much simpler. He might > be right. I'd argue it's simpler to understand each instance on its own grounds. Although a bunch of guards can get quite complex. (There was Andy A-M's example back in 2013.) The cumulative effect of the preceeding equations in the closed family is more complex. IMO. > > In retrospect, it would have been nice to have the > proposals process active when designing closed type > families; we might have come up with a better design. > There was a huge and rather repetitive (unfortunately) discussion in several rounds 2009~2012, somewhat prompted by trying to 'fix' the Haskell 2010 standard. So that we could include MPTCs in the standard. But you can't have MPTCs without FunDeps or Type Families, or without agreeing a position on overlaps. (good luck with that!) So although MPTCs were in both GHC and Hugs before 1998, they're still not 'official' >sigh<. MPTC's omission for Haskell2010 is what I meant by: > > we've lost 7~8 years of opportunity. > > My recollection at the time [of developing closed Families] > is that other approaches were > more functional-dependency-like in character. (To wit: > instance chains.) I wish Martin Sulzmann could have been more active at the time. (He occasionally expresses the intention of getting back into Haskell.) Instance guards are really a continuation of the CHR approach. So fit nicely into whole-of-program inference with type improvement. [I dislike the non-distributivity of instance chains for the same reason I dislike closed families. Although instance chains do have some nice features. Instance guards give me that feature more directly. Whereas closed type families don't give that feature at all.] > When I did the closed type family work, > I was thinking that type families were better than > functional dependencies; now, my view is much more nuanced > (leaning strongly toward fundeps instead of partial type > families). > I'm a little unsure what you mean at the top of the post about the "idea" of FunDeps vs their specific syntax. I can simulate FunDeps with superclass constraints using Type Funs and Equality constraints. This even achieves multi-directional improvement. Is that what you want to include? It took me a long time to realise this works out better than the FunDeps arrow business, especially with overlaps. The dreaded "Instances inconsistent with FunDeps" error is a devil to fiddle with. And often ends up breaking the coverage condition. [As Iavor frequently points out.] Martin pointed out that breaking coverage (using UndecidableInstances) is not as 'safe' as SPJ had been assuming. > > > I don't see what's so hard [about non-unifiability]. > > It's not nearly as hard from a fundep point of view. ... > ... [another big snip: thanks for the pointer to the paper.] > > I do have to say all this talk has made me think more > about apartness constraints in FC, at least. They might be > a touch simpler than the current story. > I think apartness is the criterion that's always applied to resolve instance selection under overlaps. The trouble is that the semantics for overlap has never been spelled out. (Nor, I suspect the criterion for a 'well-behaved' set of instances. I can volunteer that for you.) Apartness does not intrude inside constraints in the class/instance contexts, nor inside the body of a class instance/methods. It might help with instance selection wrt the rhs of type instance equations. AntC From ivan.miljenovic at gmail.com Tue May 16 05:14:50 2017 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Tue, 16 May 2017 15:14:50 +1000 Subject: [Haskell-cafe] GUI for Servant clients? Message-ID: I have a project where I'm using Servant to write a server. There will be some admin tasks involved (predominantly manual account sign-up, to restrict who is allowed to access it), and it will be much easier for the actual administrators to do so with a visual interface of some kind (because I somehow don't see them being able to use curl ;-) Whilst I could try and integrate web pages for the admin tasks into the server, from a separation of concerns and security pen-testing point of view, it would be preferable to instead expose the admin tasks as authenticated endpoints and use a client for that. Is there anything close to having a relatively automated solution to "here is the Servant API types, here is the workflow it should follow, now give me some webpages" (which I could preferably either package up using threepenny-gui, Electron or just a few HTML files I can email to the project admins - who all run Windows - to use)? It doesn't have to look pretty, just work. -- Ivan Lazar Miljenovic Ivan.Miljenovic at gmail.com http://IvanMiljenovic.wordpress.com From targen at gmail.com Tue May 16 06:08:48 2017 From: targen at gmail.com (=?UTF-8?Q?Manuel_G=C3=B3mez?=) Date: Tue, 16 May 2017 06:08:48 +0000 Subject: [Haskell-cafe] GUI for Servant clients? In-Reply-To: References: Message-ID: On Tue, May 16, 2017 at 2:16 AM Ivan Lazar Miljenovic < ivan.miljenovic at gmail.com> wrote: > Is there anything close to having a relatively automated solution to > "here is the Servant API types, here is the workflow it should follow, > now give me some webpages" (which I could preferably either package up > using threepenny-gui, Electron or just a few HTML files I can email to > the project admins - who all run Windows - to use)? It doesn't have to > look pretty, just work. > It's nowhere as plug-and-play as what you've envisioned, sadly, but perhaps you could have some success by having your endpoints output a [Siren] hypermedia representation of your server resources and then pointing one of the various API browsers[1][2][3] at it, though they do look like development has been abandoned nowdays, sadly. I even have some (very old, never published, never battle-tested, unmaintained, probably broken, not so well designed) [code] that's handy to generate Siren resource representations; it may serve as a starting point if you decide this is a reasonable way forward. [Siren]: https://github.com/kevinswiber/siren [1]: https://github.com/applicaster/siren-browser [2]: https://github.com/wurlinc/siren-browser [3]: https://github.com/kevinswiber/siren-api-browser [code]: https://github.com/mgomezch/yesod-squealer/blob/master/source/Data/Siren.hs -------------- next part -------------- An HTML attachment was scrubbed... URL: From bneijt at gmail.com Tue May 16 09:12:54 2017 From: bneijt at gmail.com (Bram Neijt) Date: Tue, 16 May 2017 11:12:54 +0200 Subject: [Haskell-cafe] Haskell performance when it comes to regex? Message-ID: Dear reader, I decided to do a little project which is a simple search and replace program for large text files. Written in Haskell, it does a few different regex matches on each line and stores them in a leveldb key-value store to create a consistent/reviewable search-replace index. It should provide for some simple/brute-force anonymization of data and therefore I called it hanon (sorry, could not think of a better name). https://github.com/BigDataRepublic/hanon The code works, but I've done some benchmarking to compare it with Python and the code is about 80x slower then doing the same thing in Python, making it useless for larger data files. I'm obviously doing something wrong. Could you give me tips on improving the performance of this code? Probably mainly looking at https://github.com/BigDataRepublic/hanon/blob/master/src/Mapper.hs where the regex code lives? Greetings, Bram From anthony_clayden at clear.net.nz Tue May 16 12:22:39 2017 From: anthony_clayden at clear.net.nz (Anthony Clayden) Date: Wed, 17 May 2017 00:22:39 +1200 Subject: [Haskell-cafe] Well-behaved instances, guards [was: [ghc-proposals/cafe] Partially applied type families] Message-ID: <591aef0f.175.546f.23016@clear.net.nz> > On Tue May 16 01:26:00 UTC 2017, Anthony Clayden wrote: (Might as well write it up, while it's fresh in my mind.) >> On Mon May 15 16:20:09 UTC 2017, Richard Eisenberg wrote: >> I do have to say all this talk has made me think more >> about apartness constraints in FC, at least. >> They might be a touch simpler than the current story. >> > The trouble is that the semantics for overlap > has never been spelled out. > (Nor, I suspect the criterion for > a 'well-behaved' set of instances. > I can volunteer that for you.) A set of instances is well-behaved wrt overlap iff for each pairing of instances, one of: 1. The instances are apart. (No overlap.) 2. One of the instances is strictly more specific. (Total overlap.) IOW the two instances unify, producing a substitution; and that substitution is exactly the more specific instance. 3. Neither instance is more specific (Partial overlap.) IOW the two instances unify, producing a substitution; and that substitution is more specific than either. And 3b. There is a third instance at exactly that substitution. So each instance becomes case 2 overlapping that third. Example: > class C a b > instance C Int b -- (A) > instance C Char b -- (B) apart from (A), case 1 > instance C Int Int -- (C) more specific than (A), case 2 > instance C a Bool -- (D) partial overlap to (A), case 3 > instance C Int Bool -- (E) intersect of (A), (D), case 3a > instance C Char Bool -- (E') 'cos (D) also overlaps (B) For a compiler to police case 3b is too hard: * It needs search for a suitable intersecting instance, so can't be validated instance-by-instance. * That intersect might be in a different module, so works against separate compilation. * That intersect (if it's declared), might itself not be well-behaved. * That intersect might not be needed. (Perhaps there's no call needing `C Int Bool`.) so it would be superfluous to declare it. (For this reason GHC doesn't look for such an instance until/unless it finds a use site.) * For the intersect, perhaps the needed definition is the same as one of the other instances. Say, `C Int Bool` defined same as `C Int b`, but different to `C a Bool`. There's no way to express that: you must repeat the code. These difficulties are somewhat relaxed for type families (not class instances): If the unifying substitution yields equal rhs's for the two equations, the instances are accepted. Example > type instance F Int b = b > type instance F a Int = a Overlap at `F Int Int`. Under either equation the result is `Int`, so this is accepted. I suspect that even with a total overlap, case 2; when GHC is trying to select the instance, it's in a state of nervous cluelessness as to the grounds/evidence for why to select an instance. Particularly if it is to reject the more specific instance: Is it sure some use site can never unify more specifically? This must be particularly hard for repeated type vars (non-linear patterns in the instance head). > instance C Bool (a, a) -- vs > instance C Bool (a, b) How do instance guards help? They eliminate the need to search for case 3a. A set of (possibly guarded) instances is well-behaved wrt overlap iff for each pairing of instances, one of: 1. They are apart. (No overlap.) 4. They overlap, so unify producing a substitution; And 4b. Under that substitution into the guards, the guards force the instances apart. Note no need to consider any other instances. Furthermore we can validate looking purely at the instance decls (including guards), we don't need to delay to possibly ambiguous uses. Re-work instances (A) to (E) above: > instance C Int b | b /~ Int -- (A) guard to de-overlap (C) > instance C Char b -- (B) apart, no need for guards > instance C Int Int -- (C) most specific, no guards > instance C a Bool | a /~ Int, -- (D) de-overlap (A) > a /~ Char -- also de-overlap (B) > -- instance C Int Bool -- (E) not needed, treat as (A) > -- instance C Char Bool -- (E') not needed, treat as (B) Show how the guards for (D) force it apart from (A): The instance heads unify to `C Int Bool`. Substitute {a ~ Int, b ~ Bool} into the guards. For (A) we get (Bool /~ Int) ==> True. For (D) we get (Int /~ Int, Int /~ Char) ==> False. So one guard (at least) is False. They're apart. The guards also drive the grounds/evidence for resolving overlapping heads. Suppose a use site wants `C Char Bool`. There's two eligible heads: (B), (D). Substitute wanted {a ~ Char, b ~ Bool} into the guards. None for (B). For (D) (a /~ Int, a /~ Char) ==> False. So select (B). And to take the repeated type var example. Declare: > instance C Bool (a, b) | a ~ b -- (F) > instance C Bool (a, b) | a /~ b -- (G) Suppose a use site wants ` C Bool (Int, b')`. That is, b' is a unification variable, not yet resolved. Substitute {a ~ Int, b ~ b'} into the guards. We have (F) (Int ~ b'); (G) (Int /~ b') Neither True; neither False. They do tell us we must improve b', to resolve the selection. Instance guards are to apply just as much for type instances. (So they can be distributed at associated types.) Example > type instance F Int b = b > type instance F a Bool | a /~ Int = a Rules for guards: a) The guards are a comma-sep list of equal (~) or apart (/~) comparisons. b) The comparands must be same-kinded. (I'll leave the poly kinded case for Richard ;-) c) Can only use type vars from the head. (I.e. not introduce extra vars, which contexts can do.) d) No type functions -- too hard, and not injective. e) Can use wildcard `_` as a type place-holder. f) Can use Type constructors to arbitrary nesting. As an example of d), the classic > type instance IsaFunction ((->) a b) = True > type instance IsaFunction c | c /~ ((->) _ _) = False Note the False case must match plain `Int` and `Maybe c'` and `Either e c'`. So putting this is valid but wouldn't be general enough: > type instance IsaFunction (c a b) | c /~ (->) = False AntC From dhelta.diaz at gmail.com Tue May 16 21:44:06 2017 From: dhelta.diaz at gmail.com (=?UTF-8?Q?Daniel_D=C3=ADaz_Casanueva?=) Date: Tue, 16 May 2017 23:44:06 +0200 Subject: [Haskell-cafe] matrix package maintenance Message-ID: Hallo Haskell-Cafe! I am the author and maintainer of the matrix package: http://hackage.haskell.org/package/matrix https://github.com/Daniel-Diaz/matrix For several reasons, mostly time related, I can't give this package the attention it deserves. GitHub issues are not being properly taken care of, and development stopped long time ago. Instead of leaving the package in this state, I thought about giving maintenance powers to anybody interested in continuing this work, or even change its direction in any (reasonable) way. I know the package has some users, so maybe any of you wants to do it. Otherwise, I guess I should try to allocate some time to at least fix some of the issues posted in GitHub. Meanwhile, sorry for the long waiting time that I have imposed on the users of this package that have reported problems or submitted PRs. King regards, Daniel Díaz. -------------- next part -------------- An HTML attachment was scrubbed... URL: From kc1956 at gmail.com Tue May 16 21:55:16 2017 From: kc1956 at gmail.com (KC) Date: Tue, 16 May 2017 14:55:16 -0700 Subject: [Haskell-cafe] matrix package maintenance In-Reply-To: References: Message-ID: Are statistics available on How many use this package? Similar hackage/stackage libraries? -- -- Sent from an expensive device which will be obsolete in a few months! :D Casey On May 16, 2017 2:44 PM, "Daniel Díaz Casanueva" wrote: > Hallo Haskell-Cafe! > > I am the author and maintainer of the matrix package: > > http://hackage.haskell.org/package/matrix > https://github.com/Daniel-Diaz/matrix > > For several reasons, mostly time related, I can't give this package the > attention it deserves. GitHub issues are not being properly taken care of, > and development stopped long time ago. > > Instead of leaving the package in this state, I thought about giving > maintenance powers to anybody interested in continuing this work, or even > change its direction in any (reasonable) way. I know the package has some > users, so maybe any of you wants to do it. Otherwise, I guess I should try > to allocate some time to at least fix some of the issues posted in GitHub. > Meanwhile, sorry for the long waiting time that I have imposed on the users > of this package that have reported problems or submitted PRs. > > King regards, > Daniel Díaz. > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From tomandltimotej at gmail.com Wed May 17 01:22:12 2017 From: tomandltimotej at gmail.com (Timotej Tomandl) Date: Wed, 17 May 2017 02:22:12 +0100 Subject: [Haskell-cafe] INLINE pragmas on unexported accessor functions Message-ID: Hello, I have the following accessor function, which is not exported out of the module: {-# INLINE left #-} left :: forall k. (Ord k) => Node k ->Node k left NullNode = NullNode left (Node _ l _) = l just for completness the type of Node is data Node k = NullNode | Node k (Node k) (Node k) I have determined upon inspecting the Core from ddump-simpl, that the INLINE pragma makes no difference, as such I would like to ask what's the convention/rule of thumb in the case of INLINE/INLINABLE pragmas on unexported accessor functions? Timo -------------- next part -------------- An HTML attachment was scrubbed... URL: From ruben.astud at gmail.com Wed May 17 05:40:16 2017 From: ruben.astud at gmail.com (Ruben Astudillo) Date: Wed, 17 May 2017 01:40:16 -0400 Subject: [Haskell-cafe] parallel package, rts ROOT vs WEAK policy and reachable sparks Message-ID: <426f3834-9306-5706-bbe0-6e408617d09b@gmail.com> Dear list This mail is long, but only the 3 last paragraphs are questions, the rest is context. Recently started reading the history of the parallel package. On the changelog of version 2.2 says (I quote) "This module has been rewritten in version 2. The main change is to the 'Strategy a' type synonym, which was previously a -> Done and is now a -> Eval a. This change helps to fix the space leak described in "Runtime Support for Multicore Haskell". The problem is that the runtime will currently retain the memory referenced by all sparks, until they are evaluated. Hence, we must arrange to evaluate all the sparks eventually, just in case they aren't evaluated in parallel, so that they don't cause a space leak. This is why we must return a "new" value after applying a Strategy, so that the application can evaluate each spark created by the Strategy." I know where are currently on version 3.3. Yet I decided to research a little more on the paper cited. On it is discussed the issue of policy for when to GC sparks. Around page 7 of the paper (I quote) ROOT: Treat (non-fizzled) sparks as roots for the garbage col- lector. That is, retain all such sparks and the graph they point to. WEAK: Only retain (non-fizzled) sparks that are reachable from the roots of the program. The problem is, neither of these policies is satisfactory. WEAK seems attractive, because it lets us discard sparks that are no longer required by the program. However, the WEAK policy is completely incompatible with strategies. Consider the parList strategy: parList :: Strategy a -> Strategy [a] parList strat [] = done parList strat (x:xs) = strat x ‘par‘ parList strat xs Each spark generated by parList is a thunk for the expression “ strat x ”; this thunk is not shared, since it is created uniquely for the purposes of creating the spark, and hence can never fizzle. Hence, the WEAK policy will discard all sparks created by parList , which is obviously undesirable(*). Question 1: Under WEAK policy, On (*) I understand the sparks cannot be fizzle'd, but how are the parList spark not reachable from the roots of the program? surely this function doesn't exist on its own. Somewhere in the program I must be a function that is executed that has an let val = ... `using` parList ... in ... val ... which would make the sparks reachable. Making it a *good* policy to have IMHO. This probably has to do with my understanding of reachable sparks. Question 2: The ROOT policy is discuted to be better, because it supports parList (and old parallel library versions). Yet, the old docs of parallel recomend to that "if you are gonna spark, make sure you use the result to avoid space leaks" ie filter you data before and only spark on that. Is this intuition correct? Question 3: What is the current situation of this? have weak pointers helped in this regard? -- Ruben From anthony_clayden at clear.net.nz Wed May 17 11:58:24 2017 From: anthony_clayden at clear.net.nz (Anthony Clayden) Date: Wed, 17 May 2017 23:58:24 +1200 Subject: [Haskell-cafe] Type Instance Partiality [was: [ghc-proposals/cafe] Partially applied type families] Message-ID: <591c3ae0.2b1.5228.29749@clear.net.nz> > On Mon May 15 16:20:09 UTC 2017, Richard Eisenberg wrote: > ... > See my recent draft paper (expanding on the "What are type families" blog post) here: > http://cs.brynmawr.edu/~rae/papers/2017/partiality/partiality.pdf .. > it's really proposing dropping type families in favor of functional dependencies > -- but only for partial type families. ... Thanks for the paper - hard going for me! Yes I can see the sense in grounding type family instances with class instances as Associated Types. I'm not finding it helpful to bring in Functional Dependencies. Your paper only mentions them towards the end [Related Work]; it might be "inspired by" FunDeps, but they don't appear in the paper as such. I'm also not finding it helpful to bring in Instance Chains [despite Garrett's involvement]. There's one major attractive feature of Instance Chains that you kinda mention ["negations" in Related Work], but which closed classes can't support. I see this as a major weakness of your proposal. > The key observation is this: partiality in types is bizarre, and we don't want it. ... Huh? Nearly all type families (and class instances) are partial. You perhaps mean "don't want it" as purist type-theoreticians(?) As a developer of applications I definitely do want it: I want to write instances only for 'sensible' patterns, and have the compiler catch usages not supported by declared instances. Your examples include many from HList: all of those are partial. I mean there's instances (eliding some details): > instance HOccurs e (HCons e l') -- found the element > instance (HOccurs e l') -- search the tail > => HOccurs e (HCons e' l') -- not this element There's deliberately not: > -- instance HOccurs e HNil -- Fail: not found Let alone: > -- instance HOccurs e (Maybe a) -- not an HList! Even if we rewrite to DataKinds, GHC has no knowledge that there's a closed set of type constructors. The only type family that usually is total is the type equality test (yielding a type-level Boolean), and your Introduction tells me that's problematic. sheesh > So, any time we use a partial type family, > you need to have a class constraint around. > The class constraint ensures that we evaluate the type family > only within its defined domain. OK. Good. > Now tied to classes, partial type families are more like > convenient syntax for functional dependencies. You perhaps mean the effect achieved by declaring > class (F a b ~ c) => C a b c where ... constraints with Type Families on a class context? OK yes that achieves the effect of FunDeps. And it's more convenient syntax. > There is also treatment of partial closed type families > via a new construct, closed classes > (somewhat like instance chains but weaker). As you predicted, I dislike closed classes even more than closed families. Let me explain what feature of Instance Chains you've left out. [Section 3.1.2 "Explicit Failure" of the 2010 paper] Sometimes I deliberately want there to be no instance for some specific pattern. I typically can't achieve that with Overlapping Instances. So: * Instance Chains have an explicit `Fail` case. [good] * HList has an instance with a Fail constraint. [clumsy] (I.e. an instance constraint to a class with no instance. See HOccursNot with class Fail in the HList paper section 6 at "Static look-up") * Type family instances (currently) don't have constraints, so this is hard work to arrange. IOW what's going on is _deliberately_ a partial type function. > > I expect AntC would prefer disequality guards over closed classes. Yes. Because I can 'precision control' which instances are available. Take HOccursNot (validates an HList to make sure some element does not occur, typically in combo with making sure the list has exactly one occurrence): > class HOccursNot e l -- no methods! use for constraint only > instance HOccursNot e HNil > -- instance omitted, see below > instance (HOccursNot e l') > => HOccursNot e (HCons e' l') | e /~ e' -- guarded Without disequality guards, the HList paper has to insert a bogus overlapping instance for a matched element type: > instance (Fail (TypeFound e)) => HOccursNot a (HCons e l') > ... The big problem with branched instances is that it was > awkward to describe the overlap between two branched instances. > AntC might argue that, if we just had disequality guards, > it would all be much simpler. He might be right. This is an important point; we must be careful. The rule for instances with guards is: no overlaps! (That is, after taking guards into account.) That is how "to describe the overlap between two branched instances": there is no overlap. The heads might overlap, but the guards force them apart. Any sort of attempt to control overlap can be stymied by imports. A closed set of instances avoids that. (I would say at cost of needing to read all preceding instances to understand the conditions for a later instance.) With guards, I can attach all the conditions to the instance itself. And then compare to each other instance to validate no overlaps -- even for imports. How would I describe the semantics, within the formalism in your partiality paper? Section 6.3: "we use axioms [xi] to witness type family reductions. That is, if there is an equation `type F Int = Bool` in scope, then we have an axiom [xi] that proves `F Int ∼ Bool`." Ok for in scope > type F a | a /~ Int = Char we get an axiom: (F a ~ Char <=> a /~ Int) -- bi-implication. [Unashamedly stolen from the CHR work.] This axiom system is coherent providing there are no other equations for `F`. Note also with disequalities we get an inference rule: a /~ b, b ~ c ===> a /~ c AntC From b at chreekat.net Wed May 17 17:32:29 2017 From: b at chreekat.net (Bryan Richter) Date: Wed, 17 May 2017 10:32:29 -0700 Subject: [Haskell-cafe] matrix package maintenance In-Reply-To: References: Message-ID: <20170517173229.GB8874@fuzzbomb> On Tue, May 16, 2017 at 02:55:16PM -0700, KC wrote: > On May 16, 2017 2:44 PM, Daniel Díaz Casanueva wrote: > > > Hallo Haskell-Cafe! > > > > I am the author and maintainer of the matrix package: > > > > http://hackage.haskell.org/package/matrix > > https://github.com/Daniel-Diaz/matrix > > > > [snip] > > Are statistics available on How many use this package? Similar > hackage/stackage libraries? These Hackage packages use matrix: http://packdeps.haskellers.com/reverse/matrix -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 801 bytes Desc: Digital signature URL: From onepoint at starurchin.org Thu May 18 07:09:07 2017 From: onepoint at starurchin.org (Jeremy Henty) Date: Thu, 18 May 2017 08:09:07 +0100 Subject: [Haskell-cafe] Why is GHCi so hard to kill? Message-ID: <20170518070907.GG18989@omphalos.singularity> If I put ghci into a loop by entering "last $ repeat ()" then the process is impossible to interrupt or kill except with "kill -KILL". (Although it can be stopped with Ctrl-Z.) "kill -TERM" does not work. The same is true if I run a runhaskell script containing "main = putStrLn $ show $ last $ repeat $ ()". Is there a reason for ghci being so unkillable? It is generally considered a bad idea for a program to ignore the TERM signal. (Details: Debian Linux Jessie 8.8, GHC 8.0.2 (built from source).) Regards, Jeremy Henty From ruben.astud at gmail.com Thu May 18 08:02:02 2017 From: ruben.astud at gmail.com (Ruben Astudillo) Date: Thu, 18 May 2017 04:02:02 -0400 Subject: [Haskell-cafe] Why is GHCi so hard to kill? In-Reply-To: <20170518070907.GG18989@omphalos.singularity> References: <20170518070907.GG18989@omphalos.singularity> Message-ID: On 18/05/17 03:09, Jeremy Henty wrote: > Is there a reason for ghci being so unkillable? It is generally > considered a bad idea for a program to ignore the TERM signal. it has to do with passing the exception to the program running inside ghci. Your example didn't manifest it because it was pure functions ghci> (last $ repeat ()) :: () and those don't catch exceptions. Yet if you put ghci> import Control.Monad (forever) ghci> forever (putStrLn "howdy") it will print forever until you press C-c on your terminal, as IO actions can react to exceptions and have a default handler for C-c. SIGKILL acted inmediatly because it isn't really a signal, the kernel just kills the process. -- -- Ruben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 488 bytes Desc: OpenPGP digital signature URL: From anselm.scholl at tu-harburg.de Thu May 18 08:07:45 2017 From: anselm.scholl at tu-harburg.de (Jonas Scholl) Date: Thu, 18 May 2017 10:07:45 +0200 Subject: [Haskell-cafe] Why is GHCi so hard to kill? In-Reply-To: <20170518070907.GG18989@omphalos.singularity> References: <20170518070907.GG18989@omphalos.singularity> Message-ID: I think the reason is that no memory allocation occurs in the loop you are trying to interrupt. Thus, the RTS can not stop the Haskell thread to terminate the program after catching the signal. You can only stop a Haskell thread if you are at a safe-point (i.e. memory allocation). If you call a function like 'last', which is already compiled, you get this behavior (you can kill it if you define last in ghci itself, because then it is interpreted instead of using the compiled version). There is a flag (-fno-omit-yields) to compile a module with additional safe-points if there is no memory allocation going on in a loop, but base is build without it, so you get the behavior you observe. On 05/18/2017 09:09 AM, Jeremy Henty wrote: > > If I put ghci into a loop by entering "last $ repeat ()" then the > process is impossible to interrupt or kill except with "kill -KILL". > (Although it can be stopped with Ctrl-Z.) "kill -TERM" does not work. > The same is true if I run a runhaskell script containing "main = > putStrLn $ show $ last $ repeat $ ()". > > Is there a reason for ghci being so unkillable? It is generally > considered a bad idea for a program to ignore the TERM signal. > > (Details: Debian Linux Jessie 8.8, GHC 8.0.2 (built from source).) > > Regards, > > Jeremy Henty > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 488 bytes Desc: OpenPGP digital signature URL: From francesco.mazzoli at digitalasset.com Thu May 18 15:14:42 2017 From: francesco.mazzoli at digitalasset.com (Francesco Mazzoli) Date: Thu, 18 May 2017 11:14:42 -0400 Subject: [Haskell-cafe] Digital Asset is hiring Haskell programmers in NYC Message-ID: TL;DR: We are hiring Haskell programmers in New York City. Feel free to talk to me about it at the NYC Compose conference, if you are around. My badge reads "Francesco Mazzoli" :). Or send me an email at . Digital Asset is a FinTech startup developing distributed ledger technology. Functional programming, and in particular Haskell, play a major role in our tech stack, specifically in the implementation of our smart contract language, DAML. DAML is a functional, typed, total programming language implementing a very general way to formally encode contracts. The designers of DAML all come from the Haskell community, with several members having a history of research in functional programming languages. Thus, we care deeply about principled solutions and formal methods. The team is currently based in Zurich and Sydney, and we're looking to expand to New York City, where the company headquarters are located. The job is on-site in Manhattan. The open role focuses on the development of the tooling supporting DAML, which is written in Haskell. The role can also involve development of production- related components operated by our customers, which are written in Scala. You can find a more corporate job posting here , although it does not reflect precisely the nature of this role. You can also find a more corporate article about DAML here . If you're at the NYC Compose conference, then feel free to talk to me (Francesco Mazzoli) about this job posting or about anything else you like. Thanks, Francesco -- This message, and any attachments, is for the intended recipient(s) only, may contain information that is privileged, confidential and/or proprietary and subject to important terms and conditions available at http://www.digitalasset.com/emaildisclaimer.html. If you are not the intended recipient, please delete this message. From alan.zimm at gmail.com Thu May 18 20:32:29 2017 From: alan.zimm at gmail.com (Alan & Kim Zimmerman) Date: Thu, 18 May 2017 22:32:29 +0200 Subject: [Haskell-cafe] Happy Parsers and constraints Message-ID: Hi all If I have a happy parser for an AST that is polymorphic, is there any way to put constraints on the individual rules? e.g. if I have data Foo a = Foo String a and a rule something like foo :: { (Show a) => Foo a } foo : otherrule { Foo (show $1) $1 } Because of the way the tables are constructed in happy, the Show constraint is not attached to the point where the rule RHS is applied. Is this simply impossible? Alan -------------- next part -------------- An HTML attachment was scrubbed... URL: From zemyla at gmail.com Thu May 18 20:59:14 2017 From: zemyla at gmail.com (Zemyla) Date: Thu, 18 May 2017 15:59:14 -0500 Subject: [Haskell-cafe] [ghc-proposals/cafe] Partially applied type families In-Reply-To: References: <591828b7.2ae.37e1.16443@clear.net.nz> Message-ID: If partial type families can be a problem, then how do you verify totality, especially considering that Any is a member of every kind, so you might have to check for F Any, F (Any Int), F (Any (Any 7) 'Just), and so on? On Mon, May 15, 2017 at 11:20 AM, Richard Eisenberg wrote: > Lots to respond to! > > I do think think there's one overarching question/theme here: Do we want functional dependencies or type-level functions? Behind AntC's arguments, I see a thrust toward functional dependencies. (Not necessarily their *syntax*, but the idea of type improvement and flexible -- that is, multidirectional -- type-level reasoning.) My dependent types work pushes me toward type-level functions. > > But I think we can have our cake and eat it too. See my recent draft paper (expanding on the "What are type families" blog post) here: http://cs.brynmawr.edu/~rae/papers/2017/partiality/partiality.pdf (This paper will appear in revised form at ICFP'17.) While the paper skirts around the issue somewhat, it's really proposing dropping type families in favor of functional dependencies -- but only for partial type families. The key observation is this: partiality in types is bizarre, and we don't want it. So, any time we use a partial type family, you need to have a class constraint around. The class constraint ensures that we evaluate the type family only within its defined domain. Now tied to classes, partial type families are more like convenient syntax for functional dependencies. There is also treatment of partial closed type families via a new construct, closed classes (somewhat like instance chains but weaker). > > I expect AntC would prefer disequality guards over closed classes. I would be interested to hear more from the community on this choice -- they're really the same as ordered equations under the hood, and it's just a choice of syntax. Maybe we can even have both. > > Now, on to individual points: > >> But this is terrible for type improvement!: > > I agree that desugaring to `case` expressions would harm type improvement. But it gives us a reliable semantics for type-level computation, something that is sorely lacking today. Can we reconcile these? Perhaps, but it will take some Hard Thought. In any case, any real implementation of these ideas would require the Hard Thought in order to be backward compatible. (This backward compatibility necessity is one of the reasons I love working with Haskell. When adding a feature to the language, we just can't take easy ways out!) > >> Closed families aren't extensible >> when I declare a new type. > > Quite true, but it's easy enough to make an open type family that calls a closed type family. In the design of closed type families, we originally thought to have (what I called) branched instances, separating out the "closedness" with the overlapping equations. In the end, it seemed simpler to have closed families have the overlapping equations and dispense with branches instances. The big problem with branched instances is that it was awkward to describe the overlap between two branched instances. AntC might argue that, if we just had disequality guards, it would all be much simpler. He might be right. > > In retrospect, it would have been nice to have the proposals process active when designing closed type families; we might have come up with a better design. > >>> so I don't agree with calling [closed type families] a misfeature, ... >> >> I think there were plenty of people >> suggesting other ways to achieve the same end. >> If "something better" comes out of the experience, >> we've lost 7~8 years of opportunity. > > By "misfeature", I didn't mean that I shouldn't have added closed type families. I'm more referring to some of the oddities pointed out in my draft paper linked above. My recollection at the time is that other approaches were more functional-dependency-like in character. (To wit: instance chains.) When I did the closed type family work, I was thinking that type families were better than functional dependencies; now, my view is much more nuanced (leaning strongly toward fundeps instead of partial type families). > > I'm not sure what you mean by "lost 7~8 years of opportunity". > >> I don't like calling it "type inequality". >> It's proof of non-unifiability. > > I call it apartness! > >> I don't see what's so hard [about non-unifiability]. > > It's not nearly as hard from a fundep point of view. That's because there's a very key difference in fundep-land. Suppose we have > >> type family F a where >> F Int = Bool > > and that's it. We can still use `F Char` in a type, even though it's nonsensical. Similarly, if a type family doesn't terminate, we can use the type family at a type that causes it to loop. If we translate the type families to fundeps, these problems go away (say, to `class C a b | a -> b; instance C Int Bool`), because a function with a type that mentions `C Char a` can never be called, as there is no `C Char xyz` instance. The key mistake behind the closed type families paper is, essentially, to assume that `F Char` is a type; all the apartness gobbledegook follows. In my draft paper, we reverse this assumption, cleaning up this theory quite nicely. > >> 5.13.2 says: "they [equality testing rules] cannot handle >> the case where Equals a a reduces to True, >> where a is locally bound type variable." >> >> ?? I thought GHC's equality test >> requires types to be grounded, >> i.e. not merely type vars, >> in order to be judged equal. >> Or did that change recently? > > > No change here -- since the advent of closed type families, GHC has been able to reduce equality over non-ground types. That's the trouble. > >> Isn't that to do with impredicativity >> and the dreaded monomorphism: >> the same typevar might get a different >> forall-qualified type in different use sites. > > Not sure what you're talking about here. GHC is resolutely predicative (in this manner, at least -- a logician would be highly flummoxed that we call a system with Type :: Type predicative!). > > > I do have to say all this talk has made me think more about apartness constraints in FC, at least. They might be a touch simpler than the current story. > > Richard > > >> On May 14, 2017, at 5:51 AM, Anthony Clayden wrote: >> >>> On Fri May 12 17:22:35 UTC 2017, Richard Eisenberg wrote: >> >>> >>> ... [in] closed type families. (We >>> would also have to eliminate non-linear patterns, >>> replacing them with some other first-class test for >>> equality. >> >>> AntC's proposed disequality constraints then become >>> straightforward pattern guards. >> >> Guards don't have to be just disequalities. >> >> If you want to eliminate non-linear patterns, >> use _equality_ guards. Full example: >> >>> type family F a b where >>> F a a = a >>> F Int b = b >>> F a Bool = a >>> >> >> Translates to: >> >>> type instance F a b | a ~ b = a >>> type instance F a b | a ~ Int, a /~ b = b >>> type instance F a b | b ~ Bool, a /~ Int, a /~ b = a >> >> (Each instance after the first >> has disequality guards to negate the earlier instances' >> equalities., i.e. the earlier instances 'shadow' the >> overlap.) >> >>> It's currently unclear to me how to do this >>> right. ... >>> >> >> Assuming we have a primitive type-level >> equality test (?~), returning type-level Bool; >> we can use helper functions. >> The first instance desugars to a call >> >>> ... = F_a_b_Eq (a ?~ b) a b >> >>> type instance F_a_b_Eq True a b = a >> >> (Needs UndecidableInstances.) >> >>> Section 5.13.2 of my thesis dwells on this, without >>> much in the way of a concrete way forward.) >> >> We use type equality testing all the time. >> In fact instance selection relies on it. >> >> 5.13.2 says: "they [equality testing rules] cannot handle >> the case where Equals a a reduces to True, >> where a is locally bound type variable." >> >> ?? I thought GHC's equality test >> requires types to be grounded, >> i.e. not merely type vars, >> in order to be judged equal. >> Or did that change recently? >> >> Isn't that to do with impredicativity >> and the dreaded monomorphism: >> the same typevar might get a different >> forall-qualified type in different use sites. >> >> Contrast types can be judged dis-equal >> without necessarily being grounded. >> [HList paper section 9 refers.] >> >> >> AntC > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From lysxia at gmail.com Thu May 18 23:34:04 2017 From: lysxia at gmail.com (Li-yao Xia) Date: Thu, 18 May 2017 19:34:04 -0400 Subject: [Haskell-cafe] parallel package, rts ROOT vs WEAK policy and reachable sparks In-Reply-To: <426f3834-9306-5706-bbe0-6e408617d09b@gmail.com> References: <426f3834-9306-5706-bbe0-6e408617d09b@gmail.com> Message-ID: <297bdd8b-bf1f-28d3-27bc-549dfdc4cc2c@gmail.com> Hi Ruben, Question 1: In your example, the sparks produced by parList are in fact not reachable. Note that as long as you don't evaluate val, there are no sparks at all: the expression (myList `using` parList strat) remains a thunk. Once you evaluate it, (strat x) is sparked for each element x, but no other reference to them is kept, since a strategy returns a unit. Question 2: If you can "filter" the values that you will actually need without evaluating them, that would be the right idea. Question 3: Take a look at the other paper linked in the docs Seq no More: Better Strategies for Parallel Haskell http://community.haskell.org/~simonmar/papers/strategies.pdf It describes the approach taken since version 2 which solves this issue of garbage collecting sparks. It also goes in a bit more detail about the problems with the original approach at the start of section 3. Regards, Li-yao On 05/17/2017 01:40 AM, Ruben Astudillo wrote: > Dear list > > This mail is long, but only the 3 last paragraphs are questions, the > rest is context. Recently started reading the history of the parallel > package. On the changelog of version 2.2 says (I quote) > > "This module has been rewritten in version 2. The main change is to > the 'Strategy a' type synonym, which was previously a -> Done and is > now a -> Eval a. This change helps to fix the space leak described > in "Runtime Support for Multicore Haskell". The problem is that the > runtime will currently retain the memory referenced by all sparks, > until they are evaluated. Hence, we must arrange to evaluate all the > sparks eventually, just in case they aren't evaluated in parallel, > so that they don't cause a space leak. This is why we must return a > "new" value after applying a Strategy, so that the application can > evaluate each spark created by the Strategy." > > I know where are currently on version 3.3. Yet I decided to research a > little more on the paper cited. On it is discussed the issue of policy > for when to GC sparks. Around page 7 of the paper (I quote) > > ROOT: Treat (non-fizzled) sparks as roots for the garbage col- > lector. That is, retain all such sparks and the graph they point to. > > WEAK: Only retain (non-fizzled) sparks that are reachable from the > roots of the program. > > The problem is, neither of these policies is satisfactory. WEAK > seems attractive, because it lets us discard sparks that are no > longer required by the program. However, the WEAK policy is > completely incompatible with strategies. Consider the parList > strategy: > > parList :: Strategy a -> Strategy [a] > parList strat [] = done > parList strat (x:xs) = strat x ‘par‘ parList strat xs > > Each spark generated by parList is a thunk for the expression “ > strat x ”; this thunk is not shared, since it is created uniquely > for the purposes of creating the spark, and hence can never fizzle. > Hence, the WEAK policy will discard all sparks created by parList > , which is obviously undesirable(*). > > Question 1: Under WEAK policy, On (*) I understand the sparks cannot be > fizzle'd, but how are the parList spark not reachable from the roots of > the program? surely this function doesn't exist on its own. Somewhere in > the program I must be a function that is executed that has an > > let val = ... `using` parList ... > in ... val ... > > which would make the sparks reachable. Making it a *good* policy to > have IMHO. This probably has to do with my understanding of reachable > sparks. > > Question 2: The ROOT policy is discuted to be better, because it > supports parList (and old parallel library versions). Yet, the old docs > of parallel recomend to that "if you are gonna spark, make sure you use > the result to avoid space leaks" ie filter you data before and only > spark on that. Is this intuition correct? > > Question 3: What is the current situation of this? have weak pointers > helped in this regard? > > -- Ruben > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From rae at cs.brynmawr.edu Fri May 19 01:05:10 2017 From: rae at cs.brynmawr.edu (Richard Eisenberg) Date: Thu, 18 May 2017 21:05:10 -0400 Subject: [Haskell-cafe] [ghc-proposals/cafe] Partially applied type families In-Reply-To: References: <591828b7.2ae.37e1.16443@clear.net.nz> Message-ID: Although I am waiting for enough time to adequately respond to AntC's latest volley, I can nab this one: > On May 18, 2017, at 4:59 PM, Zemyla wrote: > > If partial type families can be a problem, then how do you verify > totality, especially considering that Any is a member of every kind, > so you might have to check for F Any, F (Any Int), F (Any (Any 7) > 'Just), and so on? Totality is a combination of coverage and termination. It seems you are worried about coverage here -- are all possible patterns considered? However, Any doesn't pose a problem here. Because Any is an empty closed type family, it cannot appear on the left-hand side of a type family instance. (This is a change from how it was, once upon a time. But it's been this way for several releases, I think.) Termination, on the other hand, is a hard nut to crack. I offer no new nutcrackers, I'm afraid. Richard > > On Mon, May 15, 2017 at 11:20 AM, Richard Eisenberg wrote: >> Lots to respond to! >> >> I do think think there's one overarching question/theme here: Do we want functional dependencies or type-level functions? Behind AntC's arguments, I see a thrust toward functional dependencies. (Not necessarily their *syntax*, but the idea of type improvement and flexible -- that is, multidirectional -- type-level reasoning.) My dependent types work pushes me toward type-level functions. >> >> But I think we can have our cake and eat it too. See my recent draft paper (expanding on the "What are type families" blog post) here: http://cs.brynmawr.edu/~rae/papers/2017/partiality/partiality.pdf (This paper will appear in revised form at ICFP'17.) While the paper skirts around the issue somewhat, it's really proposing dropping type families in favor of functional dependencies -- but only for partial type families. The key observation is this: partiality in types is bizarre, and we don't want it. So, any time we use a partial type family, you need to have a class constraint around. The class constraint ensures that we evaluate the type family only within its defined domain. Now tied to classes, partial type families are more like convenient syntax for functional dependencies. There is also treatment of partial closed type families via a new construct, closed classes (somewhat like instance chains but weaker). >> >> I expect AntC would prefer disequality guards over closed classes. I would be interested to hear more from the community on this choice -- they're really the same as ordered equations under the hood, and it's just a choice of syntax. Maybe we can even have both. >> >> Now, on to individual points: >> >>> But this is terrible for type improvement!: >> >> I agree that desugaring to `case` expressions would harm type improvement. But it gives us a reliable semantics for type-level computation, something that is sorely lacking today. Can we reconcile these? Perhaps, but it will take some Hard Thought. In any case, any real implementation of these ideas would require the Hard Thought in order to be backward compatible. (This backward compatibility necessity is one of the reasons I love working with Haskell. When adding a feature to the language, we just can't take easy ways out!) >> >>> Closed families aren't extensible >>> when I declare a new type. >> >> Quite true, but it's easy enough to make an open type family that calls a closed type family. In the design of closed type families, we originally thought to have (what I called) branched instances, separating out the "closedness" with the overlapping equations. In the end, it seemed simpler to have closed families have the overlapping equations and dispense with branches instances. The big problem with branched instances is that it was awkward to describe the overlap between two branched instances. AntC might argue that, if we just had disequality guards, it would all be much simpler. He might be right. >> >> In retrospect, it would have been nice to have the proposals process active when designing closed type families; we might have come up with a better design. >> >>>> so I don't agree with calling [closed type families] a misfeature, ... >>> >>> I think there were plenty of people >>> suggesting other ways to achieve the same end. >>> If "something better" comes out of the experience, >>> we've lost 7~8 years of opportunity. >> >> By "misfeature", I didn't mean that I shouldn't have added closed type families. I'm more referring to some of the oddities pointed out in my draft paper linked above. My recollection at the time is that other approaches were more functional-dependency-like in character. (To wit: instance chains.) When I did the closed type family work, I was thinking that type families were better than functional dependencies; now, my view is much more nuanced (leaning strongly toward fundeps instead of partial type families). >> >> I'm not sure what you mean by "lost 7~8 years of opportunity". >> >>> I don't like calling it "type inequality". >>> It's proof of non-unifiability. >> >> I call it apartness! >> >>> I don't see what's so hard [about non-unifiability]. >> >> It's not nearly as hard from a fundep point of view. That's because there's a very key difference in fundep-land. Suppose we have >> >>> type family F a where >>> F Int = Bool >> >> and that's it. We can still use `F Char` in a type, even though it's nonsensical. Similarly, if a type family doesn't terminate, we can use the type family at a type that causes it to loop. If we translate the type families to fundeps, these problems go away (say, to `class C a b | a -> b; instance C Int Bool`), because a function with a type that mentions `C Char a` can never be called, as there is no `C Char xyz` instance. The key mistake behind the closed type families paper is, essentially, to assume that `F Char` is a type; all the apartness gobbledegook follows. In my draft paper, we reverse this assumption, cleaning up this theory quite nicely. >> >>> 5.13.2 says: "they [equality testing rules] cannot handle >>> the case where Equals a a reduces to True, >>> where a is locally bound type variable." >>> >>> ?? I thought GHC's equality test >>> requires types to be grounded, >>> i.e. not merely type vars, >>> in order to be judged equal. >>> Or did that change recently? >> >> >> No change here -- since the advent of closed type families, GHC has been able to reduce equality over non-ground types. That's the trouble. >> >>> Isn't that to do with impredicativity >>> and the dreaded monomorphism: >>> the same typevar might get a different >>> forall-qualified type in different use sites. >> >> Not sure what you're talking about here. GHC is resolutely predicative (in this manner, at least -- a logician would be highly flummoxed that we call a system with Type :: Type predicative!). >> >> >> I do have to say all this talk has made me think more about apartness constraints in FC, at least. They might be a touch simpler than the current story. >> >> Richard >> >> >>> On May 14, 2017, at 5:51 AM, Anthony Clayden wrote: >>> >>>> On Fri May 12 17:22:35 UTC 2017, Richard Eisenberg wrote: >>> >>>> >>>> ... [in] closed type families. (We >>>> would also have to eliminate non-linear patterns, >>>> replacing them with some other first-class test for >>>> equality. >>> >>>> AntC's proposed disequality constraints then become >>>> straightforward pattern guards. >>> >>> Guards don't have to be just disequalities. >>> >>> If you want to eliminate non-linear patterns, >>> use _equality_ guards. Full example: >>> >>>> type family F a b where >>>> F a a = a >>>> F Int b = b >>>> F a Bool = a >>>> >>> >>> Translates to: >>> >>>> type instance F a b | a ~ b = a >>>> type instance F a b | a ~ Int, a /~ b = b >>>> type instance F a b | b ~ Bool, a /~ Int, a /~ b = a >>> >>> (Each instance after the first >>> has disequality guards to negate the earlier instances' >>> equalities., i.e. the earlier instances 'shadow' the >>> overlap.) >>> >>>> It's currently unclear to me how to do this >>>> right. ... >>>> >>> >>> Assuming we have a primitive type-level >>> equality test (?~), returning type-level Bool; >>> we can use helper functions. >>> The first instance desugars to a call >>> >>>> ... = F_a_b_Eq (a ?~ b) a b >>> >>>> type instance F_a_b_Eq True a b = a >>> >>> (Needs UndecidableInstances.) >>> >>>> Section 5.13.2 of my thesis dwells on this, without >>>> much in the way of a concrete way forward.) >>> >>> We use type equality testing all the time. >>> In fact instance selection relies on it. >>> >>> 5.13.2 says: "they [equality testing rules] cannot handle >>> the case where Equals a a reduces to True, >>> where a is locally bound type variable." >>> >>> ?? I thought GHC's equality test >>> requires types to be grounded, >>> i.e. not merely type vars, >>> in order to be judged equal. >>> Or did that change recently? >>> >>> Isn't that to do with impredicativity >>> and the dreaded monomorphism: >>> the same typevar might get a different >>> forall-qualified type in different use sites. >>> >>> Contrast types can be judged dis-equal >>> without necessarily being grounded. >>> [HList paper section 9 refers.] >>> >>> >>> AntC >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From Andrew.Butterfield at scss.tcd.ie Fri May 19 08:43:56 2017 From: Andrew.Butterfield at scss.tcd.ie (Andrew Butterfield) Date: Fri, 19 May 2017 09:43:56 +0100 Subject: [Haskell-cafe] exporting Constructors as pattern-only Message-ID: <98B18A79-6468-4DF1-9916-C5BE9386DD46@scss.tcd.ie> All, is there any way in Haskell to export a *data* type so that importing modules can pattern match, but not use the constructors to build anything? My use case is an AST with invariant - I want the convenience of pattern matching with the safety of having to build using functions exported by the model rather than the constructors directly. e.g given data T = T1 Bool | T2 Int | TT T T t1 :: Bool -> T t2 :: Int -> T tt :: T -> T -> T from outside I can write f(T1 False) = tt (t1 True) (t2 42) but not f(T1 False) = TT (T1 True) (T2 42) ? Regards, Andrew Butterfield School of Computer Science & Statistics Trinity College Dublin 2, Ireland From evincarofautumn at gmail.com Fri May 19 09:10:52 2017 From: evincarofautumn at gmail.com (Jon Purdy) Date: Fri, 19 May 2017 02:10:52 -0700 Subject: [Haskell-cafe] exporting Constructors as pattern-only In-Reply-To: <98B18A79-6468-4DF1-9916-C5BE9386DD46@scss.tcd.ie> References: <98B18A79-6468-4DF1-9916-C5BE9386DD46@scss.tcd.ie> Message-ID: I believe you can use unidirectional pattern synonyms, and only export the patterns, not the constructors. {-# LANGUAGE PatternSynonyms #-} module Tee (T, t1, t2, pattern T1, pattern T2) where data T = MkT1 Bool | MkT2 Int | … pattern T1 a <- MkT1 a pattern T2 a <- MkT2 a … t1 :: Bool -> T t2 :: Int -> T … You can pattern-match on T1 just fine, but if you try to use it as a constructor you’ll get “non-bidirectional pattern synonym ‘T1’ used in an expression”. On Fri, May 19, 2017 at 1:43 AM, Andrew Butterfield < Andrew.Butterfield at scss.tcd.ie> wrote: > All, > > is there any way in Haskell to export a *data* type so that importing > modules can pattern match, > but not use the constructors to build anything? > > My use case is an AST with invariant - I want the convenience of pattern > matching > with the safety of having to build using functions exported by the model > rather than the constructors directly. > > e.g > > given > > data T = T1 Bool | T2 Int | TT T T > t1 :: Bool -> T > t2 :: Int -> T > tt :: T -> T -> T > > from outside I can write > > f(T1 False) = tt (t1 True) (t2 42) > > but not > > f(T1 False) = TT (T1 True) (T2 42) ? > > > Regards, > > Andrew Butterfield > School of Computer Science & Statistics > Trinity College > Dublin 2, Ireland > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From Andrew.Butterfield at scss.tcd.ie Fri May 19 09:40:34 2017 From: Andrew.Butterfield at scss.tcd.ie (Andrew Butterfield) Date: Fri, 19 May 2017 10:40:34 +0100 Subject: [Haskell-cafe] exporting Constructors as pattern-only In-Reply-To: References: <98B18A79-6468-4DF1-9916-C5BE9386DD46@scss.tcd.ie> Message-ID: <7DDF9B05-2000-421A-9102-E8D0790C7F44@scss.tcd.ie> Hi Jon, thanks for that speedy response - looks ideal! I guess though that any tests for module Tee will have to be written inside Tee, rather than in a separate test file - again this is no big deal. Regards, Andrew > On 19 May 2017, at 10:10, Jon Purdy wrote: > > I believe you can use unidirectional pattern synonyms, and only export the patterns, not the constructors. > > {-# LANGUAGE PatternSynonyms #-} > module Tee (T, t1, t2, pattern T1, pattern T2) where > > data T = MkT1 Bool | MkT2 Int | … > pattern T1 a <- MkT1 a > pattern T2 a <- MkT2 a > … > t1 :: Bool -> T > t2 :: Int -> T > … > > You can pattern-match on T1 just fine, but if you try to use it as a constructor you’ll get “non-bidirectional pattern synonym ‘T1’ used in an expression”. > > On Fri, May 19, 2017 at 1:43 AM, Andrew Butterfield > wrote: > All, > > is there any way in Haskell to export a *data* type so that importing modules can pattern match, > but not use the constructors to build anything? > > My use case is an AST with invariant - I want the convenience of pattern matching > with the safety of having to build using functions exported by the model rather than the constructors directly. > > e.g > > given > > data T = T1 Bool | T2 Int | TT T T > t1 :: Bool -> T > t2 :: Int -> T > tt :: T -> T -> T > > from outside I can write > > f(T1 False) = tt (t1 True) (t2 42) > > but not > > f(T1 False) = TT (T1 True) (T2 42) ? > > > Regards, > > Andrew Butterfield > School of Computer Science & Statistics > Trinity College > Dublin 2, Ireland > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > Andrew Butterfield School of Computer Science & Statistics Trinity College Dublin 2, Ireland -------------- next part -------------- An HTML attachment was scrubbed... URL: From schernichkin at gmail.com Fri May 19 11:17:28 2017 From: schernichkin at gmail.com (=?UTF-8?B?0KHRgtCw0L3QuNGB0LvQsNCyINCn0LXRgNC90LjRh9C60LjQvQ==?=) Date: Fri, 19 May 2017 14:17:28 +0300 Subject: [Haskell-cafe] Haskell performance when it comes to regex? In-Reply-To: References: Message-ID: Try to use Text or ByteString instead of strings. Try to use compile and execute methods ( http://hackage.haskell.org/package/regex-tdfa-1.2.1/docs/Text-Regex-TDFA-ByteString.html), make sure regex get compiled once. 2017-05-16 12:12 GMT+03:00 Bram Neijt : > Dear reader, > > I decided to do a little project which is a simple search and replace > program for large text files. > > Written in Haskell, it does a few different regex matches on each line > and stores them in a leveldb key-value store to create a > consistent/reviewable search-replace index. It should provide for some > simple/brute-force anonymization of data and therefore I called it > hanon (sorry, could not think of a better name). > > https://github.com/BigDataRepublic/hanon > > The code works, but I've done some benchmarking to compare it with > Python and the code is about 80x slower then doing the same thing in > Python, making it useless for larger data files. > > I'm obviously doing something wrong. > > Could you give me tips on improving the performance of this code? > Probably mainly looking at > > https://github.com/BigDataRepublic/hanon/blob/master/src/Mapper.hs > > where the regex code lives? > > Greetings, > > Bram > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -- Sincerely, Stanislav Chernichkin. -------------- next part -------------- An HTML attachment was scrubbed... URL: From me at alang.ca Fri May 19 12:58:49 2017 From: me at alang.ca (Alex Lang) Date: Fri, 19 May 2017 08:58:49 -0400 Subject: [Haskell-cafe] Reminder: Call for Presentations: CUFP 2017, September 7-9, Oxford, UK Message-ID: This is just a reminder that there are 3 weeks until the deadline for CUFP 2017 submissions. I'll be at Compose conference today if anybody wants to ask me any questions. My badge reads "Alexandre Lang". The CFP and the form for submitting presentations proposals can be found at: http://cufp.org/2017/call-for-presentations.html ------------------------------------------------------------------------ > 2017 Call for Presentations > > Workshop for Commercial Users of Functional Programming 2017 > Sponsored by SIGPLAN > CUFP 2017 > Co-located with ICFP 2017 > Oxford, UK > September 7-9 > Talk Proposal Submission Deadline: 9 June 2017 > > The annual CUFP event is a place where people can see how others are > using functional programming to solve real world problems; where > practitioners meet and collaborate; where language designers and users > can share ideas about the future of their favorite language; and where > one can learn practical techniques and approaches for putting functional > programming to work. > > ------------------------------------------------------------------------ > > Giving a CUFP Talk > > If you have experience using functional languages in a practical > setting, we invite you to submit a proposal to give a talk at the event. > We're looking for two kinds of talks: > > Retrospective reports are typically 25 minutes long. Now that CUFP has > run for more than a decade, we intend to invite past speakers to share > what they’ve learned after a decade spent as commercial users of > functional programming. We will favour experience reports that include > technical content. > > Technical talks are also 25 minutes long, and should focus on teaching > the audience something about a particular technique or methodology, from > the point of view of someone who has seen it play out in practice. These > talks could cover anything from techniques for building functional > concurrent applications, to managing dynamic reconfigurations, to design > recipes for using types effectively in large-scale applications. While > these talks will often be based on a particular language, they should be > accessible to a broad range of programmers. > > We strongly encourage submissions from people in communities that are > underrepresented in functional programming, including but not limited to > women; people of color; people in gender, sexual and romantic > minorities; people with disabilities; people residing in Asia, Africa, > or Latin America; and people who have never presented at a conference > before. We recognize that inclusion is an important part of our ission > to promote functional programming. So that CUFP can be a safe > environment in which participants openly exchange ideas, we abide by the > SIGPLAN Conference Anti-Harassment Policy: > > http://www.sigplan.org/Resources/Policies/Anti-harassment > > If you are interested in offering a talk, or nominating someone to do > so, please submit your presentation before 09 June 2017 via the CUFP > 2017 Presentation Submission Form: > > https://goo.gl/forms/KPloANxHHwdiaoVj2 > > You do not need to submit a paper, just a short proposal for your talk. > There will be a short scribe's report of the presentations and > discussions but not of the details of individual talks, as the meeting > is intended to be more of a discussion forum than a technical > interchange. > > Nevertheless, presentations will be recorded and presenters will be > expected to sign an ACM copyright release form. > > Note that we will need presenters to register for the CUFP workshop and > travel to Oxford at their own expense. There are some funds available to > would-be presenters who require assistance in this respect. > > ------------------------------------------------------------------------ > > Program Committee > > Alex Lang (Tsuru Capital), co-chair > Rachel Reese (Mulberry Labs), co-chair > Garrett Smith (Guild AI) > Danielle Sucher (Jane Street) > Jasper Van der Jeugt (Fugue) > Yukitoshi Suzuki (Ziosoft) > Evelina Gabasova (University of Cambridge) > Brian Mitchell (Jet.com) > > ------------------------------------------------------------------------ > > More information > > For more information on CUFP, including videos of presentations from > previous years, take a look at the CUFP website at http://cufp.org. Note > that presenters, like other attendees, will need to register for the > event. Acceptance and rejection letters will be sent out by July 15th. > Guidance on giving a great CUFP talk > > Focus on the interesting bits: Think about what will distinguish your > talk, and what will engage the audience, and focus there. There are a > number of places to look for those interesting bits. > > Setting: FP is pretty well-established in some areas, including formal > verification, financial processing, and server-side web services. An > unusual setting can be a source of interest. If you're deploying > FP-based mobile UIs or building servers on oil rigs, then the challenges > of that scenario are worth focusing on. Did FP help or hinder in > adapting to the setting? > > Technology: The CUFP audience is hungry to learn about how FP techniques > work in practice. What design patterns have you applied, and to what > areas? Did you use functional reactive programming for user interfaces, > or DSLs for playing chess, or fault-tolerant actors for large-scale > geological data processing? Teach us something about the techniques you > used, and why we should consider using them ourselves. > > Getting things done: How did you deal with large-scale software > development in the absence of pre-existing support tools that are often > expected in larger commercial environments (IDEs, coverage tools, > debuggers, profilers) and without larger, proven bodies of libraries? > Did you hit any brick walls that required support from the community? > > Don't just be a cheerleader: It's easy to write a rah-rah talk about how > well FP worked for you, but CUFP is more interesting when the talks also > cover what doesn't work. Even when the results were all great, you > should spend more time on the challenges along the way than on the parts > that went smoothly. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bneijt at gmail.com Fri May 19 16:52:05 2017 From: bneijt at gmail.com (Bram Neijt) Date: Fri, 19 May 2017 18:52:05 +0200 Subject: [Haskell-cafe] Haskell performance when it comes to regex? In-Reply-To: References: Message-ID: Thank you! I already changed to Text instead, but I thought the regex was already memoized by GHC, so that should not be a problem. I'm trying regex-applicative now, maybe that will help, but it takes some time to figure out the syntax. I'll also try to see if precompilation helps. Greetings, Bram On Fri, May 19, 2017 at 1:17 PM, Станислав Черничкин wrote: > Try to use Text or ByteString instead of strings. Try to use compile and > execute methods > (http://hackage.haskell.org/package/regex-tdfa-1.2.1/docs/Text-Regex-TDFA-ByteString.html), > make sure regex get compiled once. > > 2017-05-16 12:12 GMT+03:00 Bram Neijt : >> >> Dear reader, >> >> I decided to do a little project which is a simple search and replace >> program for large text files. >> >> Written in Haskell, it does a few different regex matches on each line >> and stores them in a leveldb key-value store to create a >> consistent/reviewable search-replace index. It should provide for some >> simple/brute-force anonymization of data and therefore I called it >> hanon (sorry, could not think of a better name). >> >> https://github.com/BigDataRepublic/hanon >> >> The code works, but I've done some benchmarking to compare it with >> Python and the code is about 80x slower then doing the same thing in >> Python, making it useless for larger data files. >> >> I'm obviously doing something wrong. >> >> Could you give me tips on improving the performance of this code? >> Probably mainly looking at >> >> https://github.com/BigDataRepublic/hanon/blob/master/src/Mapper.hs >> >> where the regex code lives? >> >> Greetings, >> >> Bram >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > > > > > -- > Sincerely, Stanislav Chernichkin. From dennis.raddle at gmail.com Fri May 19 20:22:53 2017 From: dennis.raddle at gmail.com (Dennis Raddle) Date: Fri, 19 May 2017 13:22:53 -0700 Subject: [Haskell-cafe] Haskell for Mac Message-ID: Discovered an amazing $24.99 app: Haskell for Mac. IDE with playgrounds, I expect my small personal projects to work fine with this program, and development should proceed faster now. However I can't find documentation. For instance I'm not getting auto indentation to work for me, and I don't know how to create new modules. There is a community forum, but currently broken - can't log in. Wondering if anyone here has used this app and could direct me to docs. D -------------- next part -------------- An HTML attachment was scrubbed... URL: From mihai.maruseac at gmail.com Fri May 19 20:34:08 2017 From: mihai.maruseac at gmail.com (Mihai Maruseac) Date: Fri, 19 May 2017 13:34:08 -0700 Subject: [Haskell-cafe] Haskell for Mac In-Reply-To: References: Message-ID: Hi, This is a nice app, developed my Manuel M. T. Chakravarty (BCC'ed). It is also on HCAR, https://www.haskell.org/communities/11-2016/html/report.html#sect4.5.1 (link to last edition, current one should be up in around a week). On Fri, May 19, 2017 at 1:22 PM, Dennis Raddle wrote: > Discovered an amazing $24.99 app: Haskell for Mac. IDE with playgrounds, I > expect my small personal projects to work fine with this program, and > development should proceed faster now. > > However I can't find documentation. For instance I'm not getting auto > indentation to work for me, and I don't know how to create new modules. > > There is a community forum, but currently broken - can't log in. > > Wondering if anyone here has used this app and could direct me to docs. > > D > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -- Mihai Maruseac (MM) "If you can't solve a problem, then there's an easier problem you can solve: find it." -- George Polya From anthony_clayden at clear.net.nz Sun May 21 05:33:35 2017 From: anthony_clayden at clear.net.nz (Anthony Clayden) Date: Sun, 21 May 2017 17:33:35 +1200 Subject: [Haskell-cafe] Type Instance Partiality [was: [ghc-proposals/cafe] Partially applied type families] Message-ID: <592126af.298.3400.26432@clear.net.nz> > On Wed May 17 11:58:24 UTC 2017, Anthony Clayden wrote: >> On Mon May 15 16:20:09 UTC 2017, Richard Eisenberg wrote: >> ... >> See my recent draft paper ... > Yes I can see the sense in grounding type family > instances with class instances as Associated Types. Errk I see a fly in the ointment with these 'closed classes'/associated types. Suppose: A class with two assoc types * One assoc type needs the instances in a specific sequence. * The other assoc type needs the instances in a different sequence. Here's a simple (as in daft!) example: > {-# LANGUAGE MultiParamTypeClasses, TypeFamilies, FlexibleInstances #-} > > class (Flip a ~ b, Flop b ~ a) => FlipMaybe a b where > type Flip a > type Flop b > instance (a' ~ b) => FlipMaybe (Maybe a') b where > type Flip (Maybe a') = a' > type Flop b = Maybe b > instance (a ~ b') => FlipMaybe a (Maybe b') where > type Flip a = Maybe a > type Flop (Maybe b') = b' (If we wrote a closed class in that sequence, it would get `Flip` right but `Flop` wrong.) Those instances overlap at `FlipMaybe (Maybe a') (Maybe b')`, but we can't write a coherent instance for that overlap. (Using Instance Chains, we'd want a `Fail`.) This is how the instances would go with guards: > {-# LANGUAGE ..., InstanceGuards #-} > > instance (a' ~ b) > => FlipMaybe (Maybe a') b | b /~ (Maybe _) where > type Flip (Maybe a') = a' > type Flop b | b /~ (Maybe _) = Maybe b > instance (a ~ b') > => FlipMaybe a (Maybe b') | a /~ (Maybe _) where > type Flip a | a /~ (Maybe _) = Maybe a > type Flop (Maybe b') = b' Note these don't overlap (taking guards into account). IOW we get no available instance for the overlap above. >> it's really proposing dropping type families in favor of >> functional dependencies -- but only for partial type families. ... BTW, while exploring that daft example, I kinda got it to work by declaring `Flip`, `Flop` as stand-alone closed families. But had trouble with the (~) constraints on the class. I changed them to bidirectional FunDeps | a -> b, b -> a and all worked OK. With superclass `(Flop b ~ a)` ghc 8.0.1 complained Couldn't match type ‘Flop b’ with ‘Maybe b’ arising from the superclasses of an instance declaration • In the instance declaration for ‘FlipMaybe (Maybe a') b’ and contrariwise for `(Flip a ~ b)` This is perhaps similar to trac #9918 that you mention in the partiality paper. AntC From aditya.siram at gmail.com Sun May 21 21:20:17 2017 From: aditya.siram at gmail.com (aditya siram) Date: Sun, 21 May 2017 16:20:17 -0500 Subject: [Haskell-cafe] OverloadedRecordFields in GHC 8.2.1-rc2 Message-ID: Hi, I'm trying out the GHC 8.2.1 release candidate [1], added 'OverloadedRecordFields' and I get an error saying it's an 'Unsupported Extension'. Am I doing something wrong? Thanks! -deech [1] https://mail.haskell.org/pipermail/ghc-devs/2017-May/014197.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From allbery.b at gmail.com Sun May 21 21:33:20 2017 From: allbery.b at gmail.com (Brandon Allbery) Date: Sun, 21 May 2017 17:33:20 -0400 Subject: [Haskell-cafe] OverloadedRecordFields in GHC 8.2.1-rc2 In-Reply-To: References: Message-ID: On Sun, May 21, 2017 at 5:20 PM, aditya siram wrote: > I'm trying out the GHC 8.2.1 release candidate [1], added > 'OverloadedRecordFields' and I get an error saying it's an 'Unsupported > Extension'. Am I doing something wrong? This is not in 8.2, it may be in 8.4. (The Status page is confusing: it has a header for it, but the text says: "...but no OverloadedRecordFields extension or...". Perhaps the header should be changed to "Progress on overloaded record fields"?) -- brandon s allbery kf8nh sine nomine associates allbery.b at gmail.com ballbery at sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net -------------- next part -------------- An HTML attachment was scrubbed... URL: From aditya.siram at gmail.com Sun May 21 21:36:42 2017 From: aditya.siram at gmail.com (aditya siram) Date: Sun, 21 May 2017 16:36:42 -0500 Subject: [Haskell-cafe] OverloadedRecordFields in GHC 8.2.1-rc2 In-Reply-To: References: Message-ID: Is this a mistake in the release candidate announcement? It pretty clearly states: """ This release will feature, ... * Overloaded record fields """ Thanks! -deech On Sun, May 21, 2017 at 4:33 PM, Brandon Allbery wrote: > On Sun, May 21, 2017 at 5:20 PM, aditya siram > wrote: > >> I'm trying out the GHC 8.2.1 release candidate [1], added >> 'OverloadedRecordFields' and I get an error saying it's an 'Unsupported >> Extension'. Am I doing something wrong? > > > This is not in 8.2, it may be in 8.4. > > (The Status page is confusing: it has a header for it, but the text says: > "...but no OverloadedRecordFields extension or...". Perhaps the header > should be changed to "Progress on overloaded record fields"?) > > -- > brandon s allbery kf8nh sine nomine > associates > allbery.b at gmail.com > ballbery at sinenomine.net > unix, openafs, kerberos, infrastructure, xmonad > http://sinenomine.net > -------------- next part -------------- An HTML attachment was scrubbed... URL: From allbery.b at gmail.com Sun May 21 21:42:49 2017 From: allbery.b at gmail.com (Brandon Allbery) Date: Sun, 21 May 2017 17:42:49 -0400 Subject: [Haskell-cafe] OverloadedRecordFields in GHC 8.2.1-rc2 In-Reply-To: References: Message-ID: On Sun, May 21, 2017 at 5:36 PM, aditya siram wrote: > Is this a mistake in the release candidate announcement? It pretty clearly > states: Yes, and I imagine it was caused by the confusion I pointed to. 8.2 contains more of the parts that _lead_ to ORF, but not ORF itself, but the Status page says this in a way that makes it look like ORF is included. -- brandon s allbery kf8nh sine nomine associates allbery.b at gmail.com ballbery at sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net -------------- next part -------------- An HTML attachment was scrubbed... URL: From aditya.siram at gmail.com Sun May 21 21:53:13 2017 From: aditya.siram at gmail.com (aditya siram) Date: Sun, 21 May 2017 16:53:13 -0500 Subject: [Haskell-cafe] OverloadedRecordFields in GHC 8.2.1-rc2 In-Reply-To: References: Message-ID: Got it. Thanks for clearing that up. -deech On Sun, May 21, 2017 at 4:42 PM, Brandon Allbery wrote: > On Sun, May 21, 2017 at 5:36 PM, aditya siram > wrote: > >> Is this a mistake in the release candidate announcement? It pretty >> clearly states: > > > Yes, and I imagine it was caused by the confusion I pointed to. 8.2 > contains more of the parts that _lead_ to ORF, but not ORF itself, but the > Status page says this in a way that makes it look like ORF is included. > > -- > brandon s allbery kf8nh sine nomine > associates > allbery.b at gmail.com > ballbery at sinenomine.net > unix, openafs, kerberos, infrastructure, xmonad > http://sinenomine.net > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alfredo.dinapoli at gmail.com Mon May 22 07:48:08 2017 From: alfredo.dinapoli at gmail.com (Alfredo Di Napoli) Date: Mon, 22 May 2017 09:48:08 +0200 Subject: [Haskell-cafe] Haskell performance when it comes to regex? In-Reply-To: References: Message-ID: Hi Bram, you might be interested in the “regex” package from my colleague Chris Dornan: http://regex.uk/ I know some proper performance work still needs to be done, but I would be curious to hear your experience report ;) Alfredo On 19 May 2017 at 18:52, Bram Neijt wrote: > Thank you! > > I already changed to Text instead, but I thought the regex was already > memoized by GHC, so that should not be a problem. > > I'm trying regex-applicative now, maybe that will help, but it takes > some time to figure out the syntax. I'll also try to see if > precompilation helps. > > Greetings, > > Bram > > > > On Fri, May 19, 2017 at 1:17 PM, Станислав Черничкин > wrote: > > Try to use Text or ByteString instead of strings. Try to use compile and > > execute methods > > (http://hackage.haskell.org/package/regex-tdfa-1.2.1/docs/ > Text-Regex-TDFA-ByteString.html), > > make sure regex get compiled once. > > > > 2017-05-16 12:12 GMT+03:00 Bram Neijt : > >> > >> Dear reader, > >> > >> I decided to do a little project which is a simple search and replace > >> program for large text files. > >> > >> Written in Haskell, it does a few different regex matches on each line > >> and stores them in a leveldb key-value store to create a > >> consistent/reviewable search-replace index. It should provide for some > >> simple/brute-force anonymization of data and therefore I called it > >> hanon (sorry, could not think of a better name). > >> > >> https://github.com/BigDataRepublic/hanon > >> > >> The code works, but I've done some benchmarking to compare it with > >> Python and the code is about 80x slower then doing the same thing in > >> Python, making it useless for larger data files. > >> > >> I'm obviously doing something wrong. > >> > >> Could you give me tips on improving the performance of this code? > >> Probably mainly looking at > >> > >> https://github.com/BigDataRepublic/hanon/blob/master/src/Mapper.hs > >> > >> where the regex code lives? > >> > >> Greetings, > >> > >> Bram > >> _______________________________________________ > >> Haskell-Cafe mailing list > >> To (un)subscribe, modify options or view archives go to: > >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > >> Only members subscribed via the mailman list are allowed to post. > > > > > > > > > > -- > > Sincerely, Stanislav Chernichkin. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From saurabhnanda at gmail.com Mon May 22 09:45:49 2017 From: saurabhnanda at gmail.com (Saurabh Nanda) Date: Mon, 22 May 2017 15:15:49 +0530 Subject: [Haskell-cafe] How to define a type in a TemplateHaskell function and use it in the same function? Message-ID: Cross-posted from StackOverflow: http://stackoverflow.com/questions/44107336/how-to-define-a-type-in-a-templatehaskell-function-and-use-it-in-the-same-functi Is there any way to have as single TH function, define a type, and use the type, as well? Relevant code below. `PersonPoly2` is being defined by `makeRecordSplice` and then being passed to `makeAdaptorAndInstance` (provided by Opalaye), which is also a TH function. Relevant code given below: {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} module Lib where import Data.Profunctor.Product.TH (makeAdaptorAndInstance) import Language.Haskell.TH makeRecordSplice :: Q [Dec] makeRecordSplice = [d| data PersonPoly2 a b = Person2 { id :: a , name :: b } |] makeRecordAndAdapter :: Q [Dec] makeRecordAndAdapter = do record <- makeRecordSplice adapter <- makeAdaptorAndInstance "pPerson2" (mkName "PersonPoly2") return $ record ++ adapter ------------- /home/Projects/scratch/app/Main.hs:26:1: error: ‘PersonPoly2’ is not in scope at a reify Failed, modules loaded: Lib. -- Saurabh. -------------- next part -------------- An HTML attachment was scrubbed... URL: From anthony_clayden at clear.net.nz Tue May 23 02:11:01 2017 From: anthony_clayden at clear.net.nz (Anthony Clayden) Date: Tue, 23 May 2017 14:11:01 +1200 Subject: [Haskell-cafe] How to define a type in a TemplateHaskell function and use it in the same function? Message-ID: <59239a35.fe.4fac.1826@clear.net.nz> > On Mon May 22 09:45:49 UTC 2017, Saurabh Nanda wrote: > Is there any way to have as single TH function, define a type, > and use the type, as well? In short, no. You must define/compile the TH function in a separate module, then import to where you want to use it. See second bullet of this: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#using-template-haskell And any intro to TH will also explain why it's hard. At first I was puzzled why you didn't get an error message explaining that more clearly, but I can see your usage of the TH function is also incorrect. You're trying to make a data declaration. So that must appear at top level in the program. It makes no sense to appear inside a monad. Also I suspect the imported TH function `makeAdaptorAndInstance` is trying to generate an instance declaration. This must also appear at top level, not inside a monad. > Cross-posted from StackOverflow: ... Yes, that answer has also moved the $( ... ) to top level. AntC From dsf at seereason.com Tue May 23 16:22:07 2017 From: dsf at seereason.com (David Fox) Date: Tue, 23 May 2017 09:22:07 -0700 Subject: [Haskell-cafe] Haskell performance when it comes to regex? In-Reply-To: References: Message-ID: I have been surprised at how rarely switching to Text or ByteString makes things significantly faster. If you do this you should look at Data.ByteString.Builder or Data.Text.Lazy.Builder. On Fri, May 19, 2017 at 4:17 AM, Станислав Черничкин wrote: > Try to use Text or ByteString instead of strings. Try to use compile and > execute methods (http://hackage.haskell.org/package/regex-tdfa-1.2.1/docs/ > Text-Regex-TDFA-ByteString.html), make sure regex get compiled once. > > 2017-05-16 12:12 GMT+03:00 Bram Neijt : > >> Dear reader, >> >> I decided to do a little project which is a simple search and replace >> program for large text files. >> >> Written in Haskell, it does a few different regex matches on each line >> and stores them in a leveldb key-value store to create a >> consistent/reviewable search-replace index. It should provide for some >> simple/brute-force anonymization of data and therefore I called it >> hanon (sorry, could not think of a better name). >> >> https://github.com/BigDataRepublic/hanon >> >> The code works, but I've done some benchmarking to compare it with >> Python and the code is about 80x slower then doing the same thing in >> Python, making it useless for larger data files. >> >> I'm obviously doing something wrong. >> >> Could you give me tips on improving the performance of this code? >> Probably mainly looking at >> >> https://github.com/BigDataRepublic/hanon/blob/master/src/Mapper.hs >> >> where the regex code lives? >> >> Greetings, >> >> Bram >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > > > > > -- > Sincerely, Stanislav Chernichkin. > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From corentin.dupont at gmail.com Tue May 23 17:25:00 2017 From: corentin.dupont at gmail.com (Corentin Dupont) Date: Tue, 23 May 2017 19:25:00 +0200 Subject: [Haskell-cafe] Nomyx V1.0, the only game where you can change the rules Message-ID: Hi Haskellers, in case you didn't see it on Reddit (sorry for cross-posting): I released Nomyx V1.0 ! Nomyx is a unique game where you can change the rules of the game itself while playing it. The major novelty in this version is that you can play even without knowing how to program. There is a library of rules that are ready to be proposed. A match is going on on the theme "Foundation" (and we need more players). Please join! You can login here: http://www.nomyx.net:8000/Nomyx The games are discussed on the mailing list: nomyx-game at googlegroups.com Here is a video introduction of the game: http://vimeo.com/58265498 I created a tutorial to learn how to play: http://www.corentindupont.info/blog/posts/Programming/2014-09-23-Nomyx-Language.html Some background: this is an implementation of a Nomic [1] game in Haskell (I believe the first complete implementation of a Nomic game on a computer). At the beginning, the initial rules are describing: - how to add new rules and change existing ones. For example a unanimity vote is necessary to have a new rule accepted. - how to win the game. For example you win the game if you have 5 rules accepted. But of course even that can be changed! Cheers, Corentin [1] https://en.wikipedia.org/wiki/Nomic -------------- next part -------------- An HTML attachment was scrubbed... URL: From rae at cs.brynmawr.edu Wed May 24 02:33:46 2017 From: rae at cs.brynmawr.edu (Richard Eisenberg) Date: Tue, 23 May 2017 22:33:46 -0400 Subject: [Haskell-cafe] [ghc-proposals/cafe] Partially applied type families In-Reply-To: <591a5528.271.3b05.31512@clear.net.nz> References: <591a5528.271.3b05.31512@clear.net.nz> Message-ID: > On May 15, 2017, at 9:26 PM, Anthony Clayden wrote: > > "Multidirectional type-level reasoning" is what all > functional languages do: from Robinson's unification > to Hindley-Milner to OutsideIn(X) > to System F-subscript-superscript. I disagree here: the dependently typed languages don't quite do this. For them, a type-level function is just that: it has an input that determines the output. These languages still do multi-directional type inference, but not all parts of their type system play so nicely with the multi-directional part. > > I think we can mechanically translate closed equations > to guards (equality and 'apart' tests). > The example in my earlier post > tried to show how. Agreed. > > For class instances (with overlaps), > I think there's also a mechanical translation, > but only for 'well-behaved' sets of instances. > (For Incoherent sets we don't have a chance.) > And of course as soon as some imported instance overlaps, > we have to start again to assess well-behavedness. Agreed. > > The backwards-compatibility I particularly > want to preserve is "distributed instances". > That is, putting the instance code > close to type decls and other functions that > build or consume that type. I think one other key difference between our viewpoints is that I view the whole idea of "type instance" to be a bit backward: I view type families as type-level functions. Like other functions, I want the defining equations to be all in one place. Of course, class methods are distributed in exactly the same way as type instances, but most of my work with type families has not needed the distributed aspect of them. This isn't to argue that my viewpoint is right or that other viewpoints are wrong. It's just a way to understand why we both see things the way we do. > I'd argue it's simpler to understand each instance > on its own grounds. Permit me to rewrite your sentence to something that resonates better with me: > I'd argue it's simpler to understand each *equation* > on its own grounds. I agree here, but it's a bit subtler. We aren't confused when we see > f [] = False > f _ = True even though the meaning of the second equation crucially depends on it appearing after the first. Functional programmers are used to ordering like this. But when things get more complicated, perhaps you're right. > > There was a huge and rather repetitive (unfortunately) > discussion > in several rounds 2009~2012, These dates might help to explain why I may be repeating old arguments. I became active in the community somewhere in 2012. > > I'm a little unsure what you mean at the top of the post > about the "idea" of FunDeps vs their specific syntax. By "idea", I mean traits like multidirectionality and attachment to classes. I maintain that the function-application syntax of type families is better than the relational syntax of fundeps. > A set of instances is well-behaved wrt overlap > iff for each pairing of instances, one of: Thanks for this analysis. I agree. > Rules for guards: > a) The guards are a comma-sep list > of equal (~) or apart (/~) comparisons. > b) The comparands must be same-kinded. > (I'll leave the poly kinded case for Richard ;-) > c) Can only use type vars from the head. > (I.e. not introduce extra vars, which contexts can do.) > d) No type functions -- too hard, and not injective. > e) Can use wildcard `_` as a type place-holder. > f) Can use Type constructors to arbitrary nesting. I agree here, too, though I'm not sure we need to allow ~ guards. (I think allowing them would cause confusion, with many people asking about the difference between an equality constraint and an equality guard. They're different, but I think the equality guard is useless [except as a type-level "let", I suppose].) >> The key observation is this: partiality in types is > bizarre, and we don't want it. ... > > Huh? Nearly all type families (and class instances) are > partial. > You perhaps mean "don't want it" as purist > type-theoreticians(?) Partial type families (including non-terminating ones) are bizarre because they cause wrinkles in the fabric of type families. Some of the strangeness of closed type families (Section 6 of the original Closed Type Families paper) and all of the strangeness of injective type families are caused by partiality. So I dislike partial type families for very practical reasons. Of course, when you protect a partial type family by a class constraint, then it's not troublesome: that's the point of the Constrained Type Families paper. > Sometimes I deliberately want there to be no instance > for some specific pattern. Indeed yes. And now you can, with TypeError (https://ghc.haskell.org/trac/ghc/wiki/Proposal/CustomTypeErrors, which is now available in GHC 8). The problem with instance chains is their backtracking capability, but we can have failure without backtracking. > Errk I see a fly in the ointment with these > 'closed classes'/associated types. Suppose: > > A class with two assoc types > * One assoc type needs the instances in a specific sequence. > * The other assoc type needs the instances in a different > sequence. > > Here's a simple (as in daft!) example: Hm. Interesting, illustrative example. Bottom line: You win. I'm convinced. Apartness guards (feel free to fight me on the name here -- I don't feel strongly, but somehow I like "apartness guards" more than "disequality guards") subsume OverlappingInstances (when the author of the instances has a particular desired way to resolve overlap) and closed type families. I think that the syntax of closed type families is often what the user wants, but I admit that CTFs don't cover all scenarios, especially in the context of Constrained Type Families. So I think we should keep CTFs (for now -- until Dependent Haskell is here) but add this new syntax as well, which would subsume the newly-proposed closed type classes. Even better, I think apartness guards would be very easy to implement. All the plumbing is already installed: we basically just have to add a switch. Next step: write a ghc-proposal. I'll support it. If I had the time, I'd even implement it. Thanks for getting me to think about all this in a new way! Richard From anthony_clayden at clear.net.nz Wed May 24 07:13:18 2017 From: anthony_clayden at clear.net.nz (Anthony Clayden) Date: Wed, 24 May 2017 19:13:18 +1200 Subject: [Haskell-cafe] [ghc-proposals/cafe] Partially applied type families Message-ID: <5925328e.31b.5df7.29201@clear.net.nz> > On Wed May 24 02:33:46 UTC 2017, Richard Eisenberg wrote: > ... > Thanks for getting me to think about all this > in a new way! Thanks Richard, yes I think we have large areas of agreement. So I'll cut to where we differ. > > > On May 15, 2017, at 9:26 PM, Anthony Clayden wrote: > > "Multidirectional type-level reasoning" is what all > > functional languages do: from Robinson's unification > > to Hindley-Milner to OutsideIn(X) > > to System F-subscript-superscript. > > I disagree here: the dependently typed languages don't > quite do this. Then I guess I remain to be convinced of the value of dependent typing within Haskell. > ...These languages still do multi-directional type inference, I guess you mean as needed for superclass constraints and instance constraints, so perhaps there's no practical difference. > > > > The backwards-compatibility I particularly > > want to preserve is "distributed instances". > > That is, putting the instance code > > close to type decls and other functions that > > build or consume that type. > > I think one other key difference between our viewpoints is > that I view the whole idea of "type instance" to be a bit > backward: I view type families as type-level functions. > Like other functions, I want the defining equations to be > all in one place. I'd like term-level functions to be more like instances. That is, with the equations distributed, see your example below. (Yes the set of equations must be coherent overall. That's something the compiler can check for me.) > > This isn't to argue that my viewpoint is right or that > other viewpoints are wrong. It's just a way to understand > why we both see things the way we do. Yes. > > > I'd argue it's simpler to understand each instance > > on its own grounds. > > Permit me to rewrite your sentence to something that > resonates better with me: > > > I'd argue it's simpler to understand each *equation* > > on its own grounds. > > I agree here, but it's a bit subtler. > We aren't confused when we see > > > f [] = False > > f _ = True Oh, yes I think a lot of people are confused. I think they expect the second equation is equivalent to: > f (x:xs) = True Maybe even > f ~(x:xs) = True But in the presence of bottom, that's a dangerous delusion. I'd say: if you want the True result to mean there's a non-empty list, then put that explicitly. And then we have two equations that are 'apart'. And they don't need to be sequential. Furthermore that delusion is doubly dangerous for type equations, because GHC knows nothing of closed Data Kinds. > > There was a huge and rather repetitive (unfortunately) > > discussion in several rounds 2009~2012, > > These dates might help to explain why I may be repeating > old arguments. I became active in the community somewhere > > in 2012. No, you're not repeating old arguments. Type Families, and esp. CTFs really came later. IIRC, at the time, there was a lot of suggestions, but not much push-back from anybody disagreeing. There was some doubt whether there could be a type-level disequality test. Chiefly GHC HQ just ignored the whole thing. Somebody at the time did try to write it up (viz. moi) https://ghc.haskell.org/trac/ghc/wiki/NewAxioms/DiscussionPage And someone from GHC HQ (viz. you) did acknowledge it rather later. > > I'm a little unsure what you mean at the top of the post > > about the "idea" of FunDeps vs their specific syntax. > > By "idea", I mean traits like multidirectionality and > attachment to classes. I maintain that the > function-application syntax of type families is better > than the relational syntax of fundeps. > OK I think you're saying that a class decl with superclass (~) constraints to type functions is preferable/more aesthetic. I agree. Furthermore overlap interferes with fundeps (or perhaps I mean v.v.) in horrible ways. > ...I'm not sure we need to allow ~ guards. > (I think allowing them would cause confusion, with > many people asking about the difference between an > equality constraint and an equality guard. Yes I can see the dangers of confusion. We could of course use a different operator. > ... They're different, but I think the equality guard is useless I see two main uses/benefits: 1. avoids the need for non-linear patterns in the head 2. visually points up the 'non-apartness' vs an, um. "apartness guard" (When I was figuring out Andy A-M's 2013 example, I rewrote the non-linear patterns with ~ guards, so I could figure out the apartness guards esp for the semi-apart instances. I posted the later workings to your blog https://typesandkinds.wordpress.com/2013/04/29/coincident-overlap-in-type-families/#comment-712 ) > [except as a type-level "let", I suppose].) No, they're not doing that: deliberately I don't allow guards to introduce new type vars. > ... partial type families ... > Of course, when you protect a > partial type family by a class constraint, then it's not > troublesome: that's the point of the Constrained Type > Families paper. Yes I got that loud and clear, and I agree. So the remaining issue is _how_ to protect them. > > > Sometimes I deliberately want there to be no instance > > for some specific pattern. > > Indeed yes. And now you can, with TypeError > (https://ghc.haskell.org/trac/ghc/wiki/Proposal/CustomType > Errors, which is now available in GHC 8). Ok thanks, yes that helps. Nevertheless it seems disergonomic to write an instance for a type-equal case, even with a helpful error message; when what you want is: no such instance. > > Bottom line: You win. I'm convinced. Apartness guards > (feel free to fight me on the name here -- I don't feel > strongly, but somehow I like "apartness guards" more than > "disequality guards") subsume OverlappingInstances (when > the author of the instances has a particular desired way > to resolve overlap) and closed type families. I think that > the syntax of closed type families is often what the user > wants, but I admit that CTFs don't cover all scenarios, > especially in the context of Constrained Type Families. So > I think we should keep CTFs (for now -- until Dependent > Haskell is here) but add this new syntax as well, which > would subsume the newly-proposed closed type classes. I've been (mostly in my head) calling them "Instance Guards", because I want both an eq guard and an apartness guard. > > Even better, I think apartness guards would be very easy > to implement. All the plumbing is already installed: we > basically just have to add a switch. > Yes that's what I guessed from your write-up of CTFs and "coincident overlap". What I can see will be awkward is backwards compatibility: can a class/type family with guards coexist with CTFs and with classes using overlap? > Next step: write a ghc-proposal. I'll support it. If I had > the time, I'd even implement it. I'll have a crack at the proposal. But implementing it is entirely beyond me. So thanks for saying "you win". But I'm not celebrating 'til something actually happens. (Been bitten too many times.) AntC From trupill at gmail.com Wed May 24 07:57:09 2017 From: trupill at gmail.com (Alejandro Serrano Mena) Date: Wed, 24 May 2017 09:57:09 +0200 Subject: [Haskell-cafe] [ghc-proposals/cafe] Partially applied type families In-Reply-To: References: <591a5528.271.3b05.31512@clear.net.nz> Message-ID: I know I am just jumping in the middle of an already long discussion. > > Bottom line: You win. I'm convinced. Apartness guards (feel free to fight > me on the name here -- I don't feel strongly, but somehow I like "apartness > guards" more than "disequality guards") subsume OverlappingInstances (when > the author of the instances has a particular desired way to resolve > overlap) and closed type families. I think that the syntax of closed type > families is often what the user wants, but I admit that CTFs don't cover > all scenarios, especially in the context of Constrained Type Families. So I > think we should keep CTFs (for now -- until Dependent Haskell is here) but > add this new syntax as well, which would subsume the newly-proposed closed > type classes. > > Even better, I think apartness guards would be very easy to implement. All > the plumbing is already installed: we basically just have to add a switch. > > > I would like to advise against this idea of apartness guards. I've tried myself some years ago, and I remember them being quite complicated to describe. The main problem is that apartness may end up introducing some sort of backtracking in the type checking process -- something completely undesirable. Furthermore, they make the work of the overlapping checks much harder. Alejandro -------------- next part -------------- An HTML attachment was scrubbed... URL: From corentin.dupont at gmail.com Wed May 24 08:13:41 2017 From: corentin.dupont at gmail.com (Corentin Dupont) Date: Wed, 24 May 2017 10:13:41 +0200 Subject: [Haskell-cafe] Nomyx V1.0, the only game where you can change the rules In-Reply-To: References: Message-ID: Hi Ben! Thanks a lot, it's corrected. The GUI tutorial is based on an old version of the GUI, although the principles remain the same. The new GUI is much more intuitive (I hope). Cheers! On Wed, May 24, 2017 at 10:00 AM, Ben Kolera wrote: > Hi Corentin, > > I notice that you've got some broken links on that first page. Namely: > > part 1 Nomyx GUI > > part 2 Nomyx Language > > > Just thought that you may want to know. Your game looks fun! :) > > Cheers, > Ben > > On Wed, 24 May 2017 at 03:27 Corentin Dupont > wrote: > >> Hi Haskellers, >> in case you didn't see it on Reddit (sorry for cross-posting): >> >> I released Nomyx V1.0 ! >> Nomyx is a unique game where you can change the rules of the game itself >> while playing it. >> The major novelty in this version is that you can play even without >> knowing how to program. There is a library of rules that are ready to be >> proposed. >> >> A match is going on on the theme "Foundation" (and we need more players). >> Please join! >> >> You can login here: http://www.nomyx.net:8000/Nomyx >> The games are discussed on the mailing list: nomyx-game at googlegroups.com >> >> Here is a video introduction of the game: http://vimeo.com/58265498 >> I created a tutorial to learn how to play: http://www.corentindupont. >> info/blog/posts/Programming/2014-09-23-Nomyx-Language.html >> >> Some background: this is an implementation of a Nomic [1] game in Haskell >> (I believe the first complete implementation of a Nomic game on a >> computer). At the beginning, the initial rules are describing: >> >> - how to add new rules and change existing ones. For example a >> unanimity vote is necessary to have a new rule accepted. >> - how to win the game. For example you win the game if you have 5 >> rules accepted. >> >> But of course even that can be changed! >> >> Cheers, Corentin >> >> [1] https://en.wikipedia.org/wiki/Nomic >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From anthony_clayden at clear.net.nz Wed May 24 10:47:21 2017 From: anthony_clayden at clear.net.nz (Anthony Clayden) Date: Wed, 24 May 2017 22:47:21 +1200 Subject: [Haskell-cafe] [ghc-proposals/cafe] Partially applied type families Message-ID: <592564b9.3d5.77.14770@clear.net.nz> > On Wed May 24 07:57:09 UTC 2017, Alejandro Serrano Mena wrote: > I know I am just jumping in the middle of an already long > discussion. Hi Alejandro, your input is very welcome. I know there have been many posts, so Richard's right the idea now needs writing up in detail in one place. > > > > Bottom line: You win. I'm convinced. Apartness guards .. > > > > Even better, I think apartness guards would be very easy > > to implement. All the plumbing is already installed: we > > basically just have to add a switch. > > > I would like to advise against this idea of apartness > guards. I've tried myself some years ago, and I remember > them being quite complicated to describe. ... That's interesting. What did you try? How did you test for apartness? I roughed out the rules a few posts back. Bottom of https://mail.haskell.org/pipermail/haskell-cafe/2017-May/127103.html The body of that post has worked examples. I can also translate guards into Haskell2010 + MPTCs, providing there's a primitive for type-level type comparison. (Which we could write today with Closed Type Families.) See https://mail.haskell.org/pipermail/haskell-cafe/2017-May/127090.html discussion of (?~). This is essentially the 'case-preparing' technique from HList [2004]. > The main problem is that apartness may end up > introducing some sort of backtracking > in the type checking process -- something > completely undesirable. I agree that's not just undesirable, but unacceptable. (Backtracking is a weakness of Instance chains IMO.) With the guards I'm thinking of, an instance either applies at a usage site or does not (after taking guards into account). Or type refinement hasn't advanced enough to decide. Then that instance remains 'in play'. This is exactly the same process as currently. If an instance does apply (with guards) then it is guaranteed to be the only instance. IOW all other instances are excluded. So: > Furthermore, they make the work of > the overlapping checks much harder. The guards remove any need for overlapping checks. Instead the compiler must unify the usage site with the instance head, then substitute into the guards. If a guard comes out false under that subst, reject the instance. If all guards come out true, select the instance. If some guards come out 'not proven', it needs more type refinement. So you can't have OverlappingInstances as well as InstanceGuards. (Or at least not for the same class/type family. That's a bit of backwards compatibility awkwardness I mentioned.) AntC From mihai.maruseac at gmail.com Wed May 24 14:46:32 2017 From: mihai.maruseac at gmail.com (Mihai Maruseac) Date: Wed, 24 May 2017 07:46:32 -0700 Subject: [Haskell-cafe] ANNOUNCE: Haskell Communities and Activities Report (32nd ed., May 2017) Message-ID: On behalf of all the contributors, we are pleased to announce that the Haskell Communities and Activities Report (32nd edition, May 2017) is now available, in PDF and HTML formats: http://haskell.org/communities/05-2017/report.pdf http://haskell.org/communities/05-2017/html/report.html All previous editions of HCAR can be accessed on the wiki at https://wiki.haskell.org/Haskell_Communities_and_Activities_Report Many thanks go to all the people that contributed to this report, both directly, by sending in descriptions, and indirectly, by doing all the interesting things that are reported. We hope you will find it as interesting a read as we did. If you have not encountered the Haskell Communities and Activities Reports before, you may like to know that the first of these reports was published in November 2001. Their goal is to improve the communication between the increasingly diverse groups, projects, and individuals working on, with, or inspired by Haskell. The idea behind these reports is simple: Every six months, a call goes out to all of you enjoying Haskell to contribute brief summaries of your own area of work. Many of you respond (eagerly, unprompted, and sometimes in time for the actual deadline) to the call. The editors collect all the contributions into a single report and feed that back to the community. When we try for the next update, six months from now, you might want to report on your own work, project, research area or group as well. So, please put the following into your diaries now: ======================================== End of September 2016: target deadline for contributions to the November 2017 edition of the HCAR Report ======================================== Unfortunately, many Haskellers working on interesting projects are so busy with their work that they seem to have lost the time to follow the Haskell related mailing lists and newsgroups, and have trouble even finding time to report on their work. If you are a member, user or friend of a project so burdened, please find someone willing to make time to report and ask them to "register" with the editors for a simple e-mail reminder in November (you could point us to them as well, and we can then politely ask if they want to contribute, but it might work better if you do the initial asking). Of course, they will still have to find the ten to fifteen minutes to draw up their report, but maybe we can increase our coverage of all that is going on in the community. Feel free to circulate this announcement further in order to reach people who might otherwise not see it. Enjoy! -- Mihai Maruseac (MM) "If you can't solve a problem, then there's an easier problem you can solve: find it." -- George Polya From dave at zednenem.com Wed May 24 16:02:47 2017 From: dave at zednenem.com (David Menendez) Date: Wed, 24 May 2017 12:02:47 -0400 Subject: [Haskell-cafe] [ghc-proposals/cafe] Partially applied type families In-Reply-To: <5925328e.31b.5df7.29201@clear.net.nz> References: <5925328e.31b.5df7.29201@clear.net.nz> Message-ID: On Wed, May 24, 2017 at 3:13 AM, Anthony Clayden wrote: > > > On Wed May 24 02:33:46 UTC 2017, Richard Eisenberg wrote: > > > I agree here, but it's a bit subtler. > > We aren't confused when we see > > > > > f [] = False > > > f _ = True > > Oh, yes I think a lot of people are confused. > I think they expect the second equation > is equivalent to: > > > f (x:xs) = True > > Maybe even > > > f ~(x:xs) = True > > But in the presence of bottom, > that's a dangerous delusion. I would argue those are equivalent. To get to the second equation, you would have had to reject the first equation, so at that point you already know the argument isn’t bottom. -- Dave Menendez From nikivazou at gmail.com Wed May 24 19:14:12 2017 From: nikivazou at gmail.com (Niki Vazou) Date: Wed, 24 May 2017 15:14:12 -0400 Subject: [Haskell-cafe] Accepted projects for Summer of Haskell 2017 Message-ID: Hey all, We are happy to announce the 15 projects accepted for Summer of Haskell 2017 and that the community bonding period has begun. If there are people who would like to co-mentor a project, please let us know. # Haskell.org projects 1. Safe streaming with linear types Student: Edvard Hübinette Mentor: Arnaud Spiwack 2. Improve the GHC Performance test suite Student: Shivansh Rai Mentor: Ben Gamari 3. Haskell IDE Engine Student: Zubin Duggal Mentor: Alan Zimmerman 4. Last Mile for cabal new-build Student: Francesco Gazzetta Mentor: Daniel Wagner 5. Totality checking base with Liquid Haskell Student: Sean Leffler Mentor: Niki Vazou Co-mentor: Eric Seidel 6. Modularizing haskell-mode and improving haskell-interactive-mode Student: Vasantha Ganesh Kanniappan Mentor: Gracjan Polak 7. Haskey (an embedded key-value store modeled after LMDB) Student: Henri Verroken Mentor: Steven Keuchel Co-mentor: George Karachalias 8. Improve the Shake-Based Hadrian Build System for GHC Student: Zhen Zhang Mentor: Andrey Mokhov 9. GHC Performance improvements Student: Igor Popov Mentor: Jose Calderon 10. Improvement of Hackage Matrix Builder Student: Andika Demas Riyandi Mentor: Herbert Valerio Riedel 11. WebGHC (a WebAssembly backend for GHC) Student: Michael Vogelsang Mentor: Will Fancher # code.world projects 12. Better collaborative coding features for CodeWorld Student: Parv Mor Co-mentor: Michael Chavinda Co-mentor: Anthony Green 13. Improvements to parsing, compiling, and errors for CodeWorld Student: Pranjal Tale Primary Mentor: Kyle Butt Secondary Mentor: Chris Smith 14. Exporting and sharing CodeWorld projects Student: Venkatraman Srikanth Primary Mentor: Theo Belaire Secondary Mentor: Han Wang 15. Improve editor tooling for CodeWorld Student: Eric Roberts Primary Mentor: Emin Karayel Secondary Mentor: Fernando Alegre We would like to thank all students who applied for the quality proposals. We received 68 so selecting the projects was extremely difficult. Yet, three new positions opened during selection period to accept high quality applications. Summer of Haskell 2017 is made possible by our generous sponsors: - [haskell.org](http://haskell.org) kicked things off this year by funding a student and organizing the Summer of Haskell 2017 after a successful [Summer of Haskell 2016]( https://mail.haskell.org/pipermail/haskell-cafe/2016-December/125702.html). - [Asahi Net](https://asahi-net.jp/en/) is a Japanese Internet service provider that has been running stable systems for over 25 years. They are a proud sponsor of the Summer of Haskell, and contribute to the Japanese Haskell community. - [Awake Networks](http://www.awakenetworks.com/) is building a next generation network security and analytics platform. They are a proud sponsor of the Summer of Haskell and contribute broadly to the Haskell community. - [CodeWorld](http://code.world/) is an educational project that blends mathematics and Haskell programming into a visual playground. Chris Smith has volunteered to fund two students to work on CodeWorld in particular. - [Digital Asset](http://digitalasset.com/) provides Distributed Ledger solutions for financial institutions globally. They have developed a pure, typed, functional, domain specific language for writing contracts, called DAML. They are a proud sponsor of the Summer of Haskell and contribute broadly to the Haskell community. - [Facebook](http://facebook.com/) uses Haskell in its [anti-abuse infrastructure]( https://code.facebook.com/posts/745068642270222/fighting-spam-with-haskell/), and as part of that effort we open-sourced the [Haxl]( https://github.com/facebook/Haxl) framework which is being used at scale in production to automatically parallelise data-fetching code. We're delighted to be able to support the Haskell community's efforts by sponsoring a student for this year's Summer of Haskell. - [Fugue Inc.](http://fugue.co/) radically simplifies cloud operations with its software-defined system for dynamically orchestrating and enforcing cloud infrastructure at scale. Fugue uses Haskell in its product and is proud to sponsor a student to improve the ecosystem. - [Galois](http://galois.com/) applies cutting-edge computer science and applied mathematics to solve difficult technological problems, delivering practical solutions tailored to our clients’ needs. Haskell and other functional programming languages are key tools we use in providing these solutions. - [IOHK](https://iohk.io/) is a technology company committed to using peer-to-peer technologies to provide financial services to the three billion people who don't have them. We implement our first-principles cryptographic research in Haskell and we are committed to the development of the Haskell ecosystem. - [Tweag I/O](http://tweag.io) is a network of software innovation labs across Europe. We develop novel solutions and products for our clients around the world. Haskell is key to delivering fast, correct and maintainable code. We have shipped Haskell in anything from tiny web services to large high-performance compute clusters with custom hardware. We're particularly keen to help the community grow Haskell into the strongest systems programming language and ecosystem out there. We're very proud to sponsor a student this summer to help make it happen. Davean has volunteered to fund a student expressly to work on the [Hadrian build system for GHC](/ideas.html#hadrian-ghc). Steven Keuchel has provided funds for a student to work on Haskey. Niki Vazou & Jasper Van der Jeugt -------------- next part -------------- An HTML attachment was scrubbed... URL: From rein.henrichs at gmail.com Wed May 24 23:43:35 2017 From: rein.henrichs at gmail.com (Rein Henrichs) Date: Wed, 24 May 2017 23:43:35 +0000 Subject: [Haskell-cafe] Haskell performance when it comes to regex? In-Reply-To: References: Message-ID: I recommend benchmarking with criterion and GHC profiling so you know where the slow actually is before trying to optimize anything. On Tue, May 23, 2017 at 9:26 AM David Fox wrote: > I have been surprised at how rarely switching to Text or ByteString makes > things significantly faster. If you do this you should look at > Data.ByteString.Builder or Data.Text.Lazy.Builder. > > On Fri, May 19, 2017 at 4:17 AM, Станислав Черничкин < > schernichkin at gmail.com> wrote: > >> Try to use Text or ByteString instead of strings. Try to use compile and >> execute methods ( >> http://hackage.haskell.org/package/regex-tdfa-1.2.1/docs/Text-Regex-TDFA-ByteString.html), >> make sure regex get compiled once. >> >> 2017-05-16 12:12 GMT+03:00 Bram Neijt : >> >>> Dear reader, >>> >>> I decided to do a little project which is a simple search and replace >>> program for large text files. >>> >>> Written in Haskell, it does a few different regex matches on each line >>> and stores them in a leveldb key-value store to create a >>> consistent/reviewable search-replace index. It should provide for some >>> simple/brute-force anonymization of data and therefore I called it >>> hanon (sorry, could not think of a better name). >>> >>> https://github.com/BigDataRepublic/hanon >>> >>> The code works, but I've done some benchmarking to compare it with >>> Python and the code is about 80x slower then doing the same thing in >>> Python, making it useless for larger data files. >>> >>> I'm obviously doing something wrong. >>> >>> Could you give me tips on improving the performance of this code? >>> Probably mainly looking at >>> >>> https://github.com/BigDataRepublic/hanon/blob/master/src/Mapper.hs >>> >>> where the regex code lives? >>> >>> Greetings, >>> >>> Bram >>> _______________________________________________ >>> Haskell-Cafe mailing list >>> To (un)subscribe, modify options or view archives go to: >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >>> Only members subscribed via the mailman list are allowed to post. >> >> >> >> >> -- >> Sincerely, Stanislav Chernichkin. >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. >> > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From chneukirchen at gmail.com Thu May 25 12:01:15 2017 From: chneukirchen at gmail.com (Christian Neukirchen) Date: Thu, 25 May 2017 14:01:15 +0200 Subject: [Haskell-cafe] Munich Haskell Meeting, 2017-05-29 @ 19:30 Message-ID: <87mva1i1ro.fsf@gmail.com> Dear all, Next week, our monthly Munich Haskell Meeting will take place again on Monday, May 29 at Max Emanuel Brauerei at 19h30. We'll try to get seats outside, so please be on time. For details see here: http://muenchen.haskell.bayern/dates.html If you plan to join, please add yourself to this dudle so we can reserve enough seats! It is OK to add yourself to the dudle anonymously or pseudonymously. https://dudle.inf.tu-dresden.de/haskell-munich-may-2017/ Everybody is welcome! cu, -- Christian Neukirchen http://chneukirchen.org From trebla at vex.net Fri May 26 01:26:19 2017 From: trebla at vex.net (Albert Y. C. Lai) Date: Thu, 25 May 2017 21:26:19 -0400 Subject: [Haskell-cafe] A new type of newtype --- Type-level instance diversification and resolution (tl; dr) Message-ID: <1412a619-9c69-ecea-2834-edd98ce13a2d@vex.net> When you store elements in a binary search tree, wouldn't you love to custom-order the comparison order? Wouldn't you love to do so without newtype-wrapping the element type? In fact you may actually opine that your element type should not admit a standard order in the first place (e.g., complex numbers), and whichever order used for the sake of binary search trees should stay just that and not become a general-purpose default. Perhaps more pressing to most people is when you store elements in a HashSet and you want to customize the hash function, again without either newtype-wrapping or fighting over defaults. Here is how to do that. Have a parameterized Ord class like this: {-# LANGUAGE MultiParamTypeClasses, PolyKinds, KindSignatures #-} class MyOrd (resolver :: k) a where mycmp :: p resolver -> a -> a -> Ordering instance MyOrd () Int where mycmp _ x y = compare x y data Rev instance MyOrd Rev Int where mycmp _ x y = compare y x It is also possible to get rid of the proxy parameter and use TypeApplication instead. dmwit from IRC suggests that MyOrd could be tied back to standard Ord by: instance MyOrd () a => Ord a which helps with backward compatibility. So basically use () to resolve to the standard instances (wherever a community-wide standard makes sense) and have existing standard classes tied to the new parameterized classes by resolver ~ (). Now use the parameterized Ord class for binary search trees: {-# LANGUAGE ScopedTypeVariables #-} import Data.Proxy(Proxy(Proxy)) import Data.List(foldl') data BST (resolver :: k) a = Nil | Bin !(BST resolver a) a !(BST resolver a) empty :: BST r a empty = Nil insert :: forall r a. MyOrd r a => a -> BST r a -> BST r a insert a Nil = Bin Nil a Nil insert a t@(Bin left key right) = case mycmp (Proxy :: Proxy r) a key of EQ -> t LT -> Bin (insert a left) key right GT -> Bin left key (insert a right) fromList :: MyOrd r a => [a] -> BST r a fromList xs = foldl' (flip insert) Nil xs toAscList :: BST r a -> [a] toAscList t = run t [] where run Nil = id run (Bin left key right) = run left . (key :) . run right Now we have it. toAscList (fromList [3,1,4,15,9,2,6,5,38] :: BST () Int) evaluates to [1,2,3,4,5,6,9,15,38] toAscList (fromList [3,1,4,15,9,2,6,5,38] :: BST Rev Int) evaluates to [38,15,9,6,5,4,3,2,1] and both terms have the same type [Int]. The second term does not have to have type [Down Int]. Other applications include: Custom-making equivalence relations without calling them Eq; alternative interfaces to groupBy, sortBy, maximumBy, etc.; SML-style functorial programming; and liberating Complex from Ord. I thank jadrian from IRC for proposing "named instance": > so instead of "instance Num n => Monoid (Sum n) where" we'd write e.g. > "instance Sum of Num n => Monoid n where" and use it as "Sum.mempty" which stimulated me to think "oh we can emulate that by multiple parameter type class..." From codygman.consulting at gmail.com Fri May 26 06:24:45 2017 From: codygman.consulting at gmail.com (Cody Goodman) Date: Fri, 26 May 2017 01:24:45 -0500 Subject: [Haskell-cafe] Adding support for user defined data types to cassandra-cql Message-ID: Hello all, I wrote some template Haskell code that looks up data in a cassandra database in the system.schema_columns table using this library: https://github.com/the-real-blackh/cassandra-cql/blob/master/Database/Cassandra/CQL.hs Currently cassandra-cql lets you make queries like this: getColFamInfo :: Query Rows () (Text, Text, Text, Text, Text) getColFamInfo = "select keyspace_name, columnfamily_name, column_name, type, validator from system.schema_columns" And then it returns type (Text,Text,Text,Text,Text). I'd prefer to be able to write a query like: data MyRecord = MyRecord { a :: Text, b :: Text, c :: Text, d :: Text } getColFamInfo :: Query Rows () (Maybe MyRecord) getColFamInfo = "select keyspace_name, columnfamily_name, column_name, type, validator from system.schema_columns" Point being: I have types being generated from cassandra, but I have no idea where I'd start modifying the cassandra-cql library to use those types. Could anyone offer any direction? Also... Below is a snippet of how Query is implemented, but you can find the full code here: https://github.com/the-real-blackh/cassandra-cql/blob/master/Database/Cassandra/CQL.hs Query Looks like: { - START CODE -} -- | The first type argument for Query. Tells us what kind of query it is. data Style = Schema -- ^ A query that modifies the schema, such as DROP TABLE or CREATE TABLE | Write -- ^ A query that writes data, such as an INSERT or UPDATE | Rows -- ^ A query that returns a list of rows, such as SELECT -- | The text of a CQL query, along with type parameters to make the query type safe. -- The type arguments are 'Style', followed by input and output column types for the -- query each represented as a tuple. -- -- The /DataKinds/ language extension is required for 'Style'. data Query :: Style -> * -> * -> * where Query :: QueryID -> Text -> Query style i o deriving Show queryText :: Query s i o -> Text queryText (Query _ txt) = txt instance IsString (Query style i o) where fromString = query . T.pack -- | Construct a query. Another way to construct one is as an overloaded string through -- the 'IsString' instance if you turn on the /OverloadedStrings/ language extension, e.g. -- -- > {-# LANGUAGE OverloadedStrings #-} -- > ... -- > -- > getOneSong :: Query Rows UUID (Text, Text, Maybe Text) -- > getOneSong = "select title, artist, comment from songs where id=?" query :: Text -> Query style i o query cql = Query (QueryID . hash . T.encodeUtf8 $ cql) cql { - END CODE -} Thanks, Cody Goodman -------------- next part -------------- An HTML attachment was scrubbed... URL: From dennis.raddle at gmail.com Fri May 26 23:27:29 2017 From: dennis.raddle at gmail.com (Dennis Raddle) Date: Fri, 26 May 2017 16:27:29 -0700 Subject: [Haskell-cafe] problems with stack, config.yaml Message-ID: A year ago I tried to install stack on my MacBook. Just recently I tried again, and it asked me if I wanted to upgrade rather than install. I did so, but got an error (some message from GHC saying 'the thing that should never happen, happened' or something like that). So I thought, okay let me try uninstalling stack first, then installing it, and going from there. So I did that, and I'm working the stack tutorial, and upon doing "stack setup" I got a parse error in config.yaml. "Error in $.params: failed to parse field 'params', expected Map k a, encountered String" As far as the question of where I got my config.yaml from, I edited something that was there to add some specific information, but I am not sure if I changed anything else. Here is the config.yaml that produces the above error: # This file contains default non-project-specific settings for 'stack', used # in all projects. For more information about stack's configuration, see # http://docs.haskellstack.org/en/stable/yaml_configuration/ # The following parameters are used by "stack new" to automatically fill fields # in the cabal config. We recommend uncommenting them and filling them out if # you intend to use 'stack new'. # See https://docs.haskellstack.org/en/stable/yaml_configuration/#templates templates: params: author-name:Dennis author-email:dennisraddle at gmail.com category:programming copyright:2017 github-username:Dennis -------------- next part -------------- An HTML attachment was scrubbed... URL: From hyarion at iinet.net.au Fri May 26 23:46:15 2017 From: hyarion at iinet.net.au (Ben) Date: Sat, 27 May 2017 09:46:15 +1000 Subject: [Haskell-cafe] problems with stack, config.yaml In-Reply-To: References: Message-ID: <6F1230A8-6B0A-4C52-B18C-92A559D23335@iinet.net.au> On 27 May 2017 9:27:29 am AEST, Dennis Raddle wrote: >A year ago I tried to install stack on my MacBook. Just recently I >tried >again, and it asked me if I wanted to upgrade rather than install. I >did >so, but got an error (some message from GHC saying 'the thing that >should >never happen, happened' or something like that). So I thought, okay let >me >try uninstalling stack first, then installing it, and going from there. > >So I did that, and I'm working the stack tutorial, and upon doing >"stack >setup" I got a parse error in config.yaml. > > "Error in $.params: failed to parse field 'params', expected Map k a, >encountered String" > >As far as the question of where I got my config.yaml from, I edited >something that was there to add some specific information, but I am not >sure if I changed anything else. Here is the config.yaml that produces >the >above error: > ># This file contains default non-project-specific settings for 'stack', >used ># in all projects. For more information about stack's configuration, >see ># http://docs.haskellstack.org/en/stable/yaml_configuration/ > ># The following parameters are used by "stack new" to automatically >fill >fields ># in the cabal config. We recommend uncommenting them and filling them >out >if ># you intend to use 'stack new'. ># See >https://docs.haskellstack.org/en/stable/yaml_configuration/#templates >templates: > params: > author-name:Dennis > author-email:dennisraddle at gmail.com > category:programming > copyright:2017 > github-username:Dennis Hi Dennis, The problem is just that the structure of your YAML config file is off, so it doesn't say what you think it says. Where you have things like "author-name:Dennis" you need a space after the colon for YAML to interpret it as a key value pair in a map. With what you have currently, the whole contents of your "params" section is just one string split over several lines, rather than a map (which is more or less what the error message is reporting). You can see how YAML interprets your file here: https://yaml-online-parser.appspot.com/ -- Ben -------------- next part -------------- An HTML attachment was scrubbed... URL: From fvillanustre at gmail.com Sat May 27 08:51:39 2017 From: fvillanustre at gmail.com (Flavio Villanustre) Date: Sat, 27 May 2017 04:51:39 -0400 Subject: [Haskell-cafe] wiki account request In-Reply-To: References: Message-ID: I just created an account for you. You should be receiving a temporary password via email in the next few minutes. Please let me know if you need any further assistance to log in. Best, Flavio On May 27, 2017 02:50, "jzeus" wrote: username "jzeus" -------------- next part -------------- An HTML attachment was scrubbed... URL: From frank at fstaals.net Sat May 27 14:27:21 2017 From: frank at fstaals.net (Frank Staals) Date: Sat, 27 May 2017 10:27:21 -0400 Subject: [Haskell-cafe] A new type of newtype --- Type-level instance diversification and resolution (tl; dr) In-Reply-To: <1412a619-9c69-ecea-2834-edd98ce13a2d@vex.net> (Albert Y. C. Lai's message of "Thu, 25 May 2017 21:26:19 -0400") References: <1412a619-9c69-ecea-2834-edd98ce13a2d@vex.net> Message-ID: "Albert Y. C. Lai" writes: > > > class MyOrd (resolver :: k) a where > mycmp :: p resolver -> a -> a -> Ordering > > > > data BST (resolver :: k) a = Nil | Bin !(BST resolver a) a !(BST resolver a) Oh that is a pretty neat trick. I have to remember that. The unfortunate thing even with it, you would need to reimplement all of the data structures around to use it. I wonder if there is a way to use something like this together with existing data structures such as Data.Map/Set etc. -- - Frank From litchard.michael at gmail.com Sat May 27 14:32:36 2017 From: litchard.michael at gmail.com (Michael Litchard) Date: Sat, 27 May 2017 07:32:36 -0700 Subject: [Haskell-cafe] Yesod Problem - passing values inside a route Message-ID: Below I have an example from the Yesod book. The form action maps to a route. How do I pass a value to that route. I know it has something to do with ^ but I can't see to make it work right. {-# LANGUAGE MultiParamTypeClasses #-}{-# LANGUAGE OverloadedStrings #-}{-# LANGUAGE QuasiQuotes #-}{-# LANGUAGE TemplateHaskell #-}{-# LANGUAGE TypeFamilies #-}import Control.Applicativeimport Data.Text (Text)import Yesod data App = App mkYesod "App" [parseRoutes|/ HomeR GET/input InputR GET|] instance Yesod App instance RenderMessage App FormMessage where renderMessage _ _ = defaultFormMessage data Person = Person { personName :: Text , personAge :: Int } deriving Show getHomeR :: Handler Html getHomeR = defaultLayout [whamlet|
<--- problem line -- want to do this

My name is and I am years old. |] getInputR :: Text -> Handler Html getInputR label = do person <- runInputGet $ Person <$> ireq textField label <*> ireq intField "age" defaultLayout [whamlet|

#{show person}|] main :: IO () main = warp 3000 App -------------- next part -------------- An HTML attachment was scrubbed... URL: From brucker at spamfence.net Sat May 27 20:17:10 2017 From: brucker at spamfence.net (Achim D. Brucker) Date: Sat, 27 May 2017 21:17:10 +0100 Subject: [Haskell-cafe] ThEdu'17: 2nd Call for Extended Abstracts & Demonstrations Message-ID: <20170527201710.qqwn5vjvc6ihgpu2@fujikawa.home.brucker.ch> (Apologies for duplicates) Call for Extended Abstracts & Demonstrations ThEdu'17 Theorem proving components for Educational software http://www.uc.pt/en/congressos/thedu/thedu17 at CADE 26 International Conference on Automated Deduction 6-11 August 2017 Gothenburg, Sweden http://www.cade-26.info/ ThEdu'17 Scope Computer Theorem Proving is becoming a paradigm as well as a technological base for a new generation of educational software in science, technology, engineering and mathematics. The workshop brings together experts in automated deduction with experts in education in order to further clarify the shape of the new software generation and to discuss existing systems. Topics of interest include: * methods of automated deduction applied to checking students' input; * methods of automated deduction applied to prove post-conditions for particular problem solutions; * combinations of deduction and computation enabling systems to propose next steps; * automated provers specific for dynamic geometry systems; * proof and proving in mathematics education. Important Dates Extended Abstracts: 18 June 2017 Author Notification: 2 July 2017 Final Version: 16 July 2017 Workshop Day: 6 August 2017 Submission Interested researchers are invited to submit extended abstracts and system descriptions. Both kinds of submissions should be approximately 5 pages in length and present original unpublished work not submitted elsewhere. Submission is in PDF format via easychair, https://easychair.org/conferences/?conf=thedu17 formatted according to http://www.easychair.org/publications/easychair.zip The extended abstracts and system descriptions will be made available online. At least one author is expected to presents his/her submission at ThEdu'17. Joint publication in companion with other CADE26 events is under consideration (as a volume in the EPiC Series in Computing). Program Committee Francisco Botana, University of Vigo at Pontevedra, Spain Achim D. Brucker, University of Sheffield, United Kingdom Filip Maric, University of Belgrade, Serbia Walther Neuper, Graz University of Technology, Austria (co-chair) Pavel Pech , University of South Bohemia, Czech Republic Pedro Quaresma, University of Coimbra, Portugal (co-chair) Vanda Santos, CISUC, Portugal Wolfgang Schreiner, Johannes Kepler University, Austria Burkhart Wolff, University Paris-Sud, France -- Dr. Achim D. Brucker | Software Assurance & Security | University of Sheffield https://www.brucker.ch | https://logicalhacking.com/blog @adbrucker | @logicalhacking From dennis.raddle at gmail.com Sun May 28 06:41:06 2017 From: dennis.raddle at gmail.com (Dennis Raddle) Date: Sat, 27 May 2017 23:41:06 -0700 Subject: [Haskell-cafe] stack problems Message-ID: Trying to learn stack. I'm following the tutorial on this page: https://docs.haskellstack.org/en/stable/GUIDE/ I built helloworld. Then I modified Lib.hs to include Data.Text.IO, as the tutorial specifies. I typed 'stack build' and got the error that the text package wasn't installed, as the tutorial says I would. I then modified helloworld.cabal to have these lines: build-depends: base , helloworld , text and typed 'stack build' again. I got the exact same output - an error on building Lib.hs, 'Failed to load interface for Data.Text.IO. I checked that I really modified al lthe right files and can't find anything I did wrong. -------------- next part -------------- An HTML attachment was scrubbed... URL: From dct25-561bs at mythic-beasts.com Sun May 28 06:48:18 2017 From: dct25-561bs at mythic-beasts.com (David Turner) Date: Sun, 28 May 2017 07:48:18 +0100 Subject: [Haskell-cafe] stack problems In-Reply-To: References: Message-ID: Hi, It looks like you've added `text` to the list of dependencies for the executable, rather than the library. Try adding it to the `build-depends` field of the library block in the cabal file instead. Cheers, David On 28 May 2017 07:41, "Dennis Raddle" wrote: > Trying to learn stack. I'm following the tutorial on this page: > > https://docs.haskellstack.org/en/stable/GUIDE/ > > I built helloworld. Then I modified Lib.hs to include Data.Text.IO, as > the tutorial specifies. I typed 'stack build' and got the error that the > text package wasn't installed, as the tutorial says I would. I then > modified helloworld.cabal to have these lines: > > build-depends: base > , helloworld > , text > > and typed 'stack build' again. I got the exact same output - an error on > building Lib.hs, 'Failed to load interface for Data.Text.IO. I checked > that I really modified al lthe right files and can't find anything I did > wrong. > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From damian.nadales at gmail.com Sun May 28 06:49:06 2017 From: damian.nadales at gmail.com (Damian Nadales) Date: Sun, 28 May 2017 08:49:06 +0200 Subject: [Haskell-cafe] stack problems In-Reply-To: References: Message-ID: Without seeing all the files I'd guess you added the `text` package under the `build-depends` of the executable, and not of the library. Is that correct? On Sun, May 28, 2017 at 8:41 AM, Dennis Raddle wrote: > Trying to learn stack. I'm following the tutorial on this page: > > https://docs.haskellstack.org/en/stable/GUIDE/ > > I built helloworld. Then I modified Lib.hs to include Data.Text.IO, as the > tutorial specifies. I typed 'stack build' and got the error that the text > package wasn't installed, as the tutorial says I would. I then modified > helloworld.cabal to have these lines: > > build-depends: base > , helloworld > , text > > and typed 'stack build' again. I got the exact same output - an error on > building Lib.hs, 'Failed to load interface for Data.Text.IO. I checked that > I really modified al lthe right files and can't find anything I did wrong. > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From damian.nadales at gmail.com Sun May 28 07:24:47 2017 From: damian.nadales at gmail.com (Damian Nadales) Date: Sun, 28 May 2017 09:24:47 +0200 Subject: [Haskell-cafe] List instance of Alternative: why (++)? In-Reply-To: References: Message-ID: > It's hard to look at laws, because there's apparently little agreement on > the proper laws for Alternative. It looks possible that as an Applicative > and Alternative, this would be fine; but the Alternative instance you > propose would work in odd ways with the Monad instance. That is, if f x == > [] for any x in (non-empty) xs, then something like (xs <|> ys) >>= f would > yield an empty list, while (xs >>= f) <|> (ys >>= f) would not. But, this In this case `(xs >>= f) <|> (ys >>= f)` will also be empty as far as I can see... I'm also trying to make some sense out of this definition of alternative for lists. For `Maybe` we also have a left biased alternative, and despite this I find it quite useful... > isn't a law or anything, you could chalk it up as counter-intuitive, but not > disqualifying. > > On Fri, May 5, 2017 at 11:12 PM, Theodore Lief Gannon > wrote: >> >> Fiddling around, I found myself wanting: >> >> coalesce :: [a] -> [a] -> [a] >> -- or -- :: (Foldable t) => t a -> t a -> t a >> coalesce a b = if null a then b else a >> >> I expected this to be (<|>) (it is for Maybe!) but instead I find no >> canonical implementation of it anywhere, and what seems like a useless >> instance Alternative []. What's the rationale? >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From dennis.raddle at gmail.com Sun May 28 07:43:37 2017 From: dennis.raddle at gmail.com (Dennis Raddle) Date: Sun, 28 May 2017 00:43:37 -0700 Subject: [Haskell-cafe] stack problems In-Reply-To: References: Message-ID: That solved it, thank you. On Sat, May 27, 2017 at 11:48 PM, David Turner < dct25-561bs at mythic-beasts.com> wrote: > Hi, > > It looks like you've added `text` to the list of dependencies for the > executable, rather than the library. Try adding it to the `build-depends` > field of the library block in the cabal file instead. > > Cheers, > > David > > On 28 May 2017 07:41, "Dennis Raddle" wrote: > >> Trying to learn stack. I'm following the tutorial on this page: >> >> https://docs.haskellstack.org/en/stable/GUIDE/ >> >> I built helloworld. Then I modified Lib.hs to include Data.Text.IO, as >> the tutorial specifies. I typed 'stack build' and got the error that the >> text package wasn't installed, as the tutorial says I would. I then >> modified helloworld.cabal to have these lines: >> >> build-depends: base >> , helloworld >> , text >> >> and typed 'stack build' again. I got the exact same output - an error on >> building Lib.hs, 'Failed to load interface for Data.Text.IO. I checked >> that I really modified al lthe right files and can't find anything I did >> wrong. >> >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From chris at chrisdornan.com Sun May 28 12:22:01 2017 From: chris at chrisdornan.com (Chris Dornan) Date: Sun, 28 May 2017 13:22:01 +0100 Subject: [Haskell-cafe] Haskell performance when it comes to regex? In-Reply-To: <019C1A5D-9053-4DB1-A3C4-3E2856784A7E@gmail.com> References: <019C1A5D-9053-4DB1-A3C4-3E2856784A7E@gmail.com> Message-ID: <1887CACF-C62A-4174-AE18-3DFFDD2882CC@regex.uk> Hi Bram, Sorry for being a bit late to this -- I have been on the road. I have switched over you example to pre-compile the REs and use ByteString and can see 13x speedup on scan and a 9x speedup on mapping. Curiously, nearly all of that speedup seems to be gained by lifting the RE compilation out of the loop but I am pretty sure there are gains to be had from re-writing the loops. Do you have the Python code that was performing 80x better? Chris From: Alfredo Di Napoli Date: Monday, 22 May 2017 at 08:48 To: Bram Neijt Cc: Станислав Черничкин , haskell-cafe , Chris Dornan Subject: Re: [Haskell-cafe] Haskell performance when it comes to regex? Hi Bram, you might be interested in the “regex” package from my colleague Chris Dornan: http://regex.uk/ I know some proper performance work still needs to be done, but I would be curious to hear your experience report ;) Alfredo On 19 May 2017 at 18:52, Bram Neijt wrote: Thank you! I already changed to Text instead, but I thought the regex was already memoized by GHC, so that should not be a problem. I'm trying regex-applicative now, maybe that will help, but it takes some time to figure out the syntax. I'll also try to see if precompilation helps. Greetings, Bram On Fri, May 19, 2017 at 1:17 PM, Станислав Черничкин wrote: > Try to use Text or ByteString instead of strings. Try to use compile and > execute methods > (http://hackage.haskell.org/package/regex-tdfa-1.2.1/docs/Text-Regex-TDFA-ByteString.html), > make sure regex get compiled once. > > 2017-05-16 12:12 GMT+03:00 Bram Neijt : >> >> Dear reader, >> >> I decided to do a little project which is a simple search and replace >> program for large text files. >> >> Written in Haskell, it does a few different regex matches on each line >> and stores them in a leveldb key-value store to create a >> consistent/reviewable search-replace index. It should provide for some >> simple/brute-force anonymization of data and therefore I called it >> hanon (sorry, could not think of a better name). >> >> https://github.com/BigDataRepublic/hanon >> >> The code works, but I've done some benchmarking to compare it with >> Python and the code is about 80x slower then doing the same thing in >> Python, making it useless for larger data files. >> >> I'm obviously doing something wrong. >> >> Could you give me tips on improving the performance of this code? >> Probably mainly looking at >> >> https://github.com/BigDataRepublic/hanon/blob/master/src/Mapper.hs >> >> where the regex code lives? >> >> Greetings, >> >> Bram >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > > > > > -- > Sincerely, Stanislav Chernichkin. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From michael at snoyman.com Sun May 28 13:12:44 2017 From: michael at snoyman.com (Michael Snoyman) Date: Sun, 28 May 2017 13:12:44 +0000 Subject: [Haskell-cafe] Yesod Problem - passing values inside a route In-Reply-To: References: Message-ID: I'm on mobile now, but you want to use the ^?{} syntax which allows you to pass a pair of route and query string parameters. There's an example in the Shakespeare chapter of the book. On Sat, May 27, 2017, 8:34 AM Michael Litchard wrote: > Below I have an example from the Yesod > book. The form action maps to a > route. How do I pass a value to that route. I know it has something to do > with ^ but I can't see to make it work right. > > {-# LANGUAGE MultiParamTypeClasses #-}{-# LANGUAGE OverloadedStrings #-}{-# LANGUAGE QuasiQuotes #-}{-# LANGUAGE TemplateHaskell #-}{-# LANGUAGE TypeFamilies #-}import Control.Applicativeimport Data.Text (Text)import Yesod > data App = App > > mkYesod "App" [parseRoutes|/ HomeR GET/input InputR GET|] > > instance Yesod App > > instance RenderMessage App FormMessage where > renderMessage _ _ = defaultFormMessage > data Person = Person > { personName :: Text > , personAge :: Int > } > deriving Show > > getHomeR :: Handler Html > getHomeR = defaultLayout > [whamlet| > <--- problem line -- want to do this >

> My name is > > and I am > > years old. > > |] > > getInputR :: Text -> Handler Html > getInputR label = do > person <- runInputGet $ Person > <$> ireq textField label > <*> ireq intField "age" > defaultLayout [whamlet|

#{show person}|] > > main :: IO () > main = warp 3000 App > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From cdsmith at gmail.com Sun May 28 16:11:12 2017 From: cdsmith at gmail.com (Chris Smith) Date: Sun, 28 May 2017 09:11:12 -0700 Subject: [Haskell-cafe] List instance of Alternative: why (++)? In-Reply-To: References: Message-ID: My understanding of the proposed instance was that if xs >>= f is [], then (xs >>= f) | (ys >>= f) would be ys >>= f. That may not necessarily be empty. Consider: f 42 = [42] f _ = [] xs = [1,2,3] ys = [42] On Sun, May 28, 2017 at 12:24 AM, Damian Nadales wrote: > > It's hard to look at laws, because there's apparently little agreement on > > the proper laws for Alternative. It looks possible that as an > Applicative > > and Alternative, this would be fine; but the Alternative instance you > > propose would work in odd ways with the Monad instance. That is, if f x > == > > [] for any x in (non-empty) xs, then something like (xs <|> ys) >>= f > would > > yield an empty list, while (xs >>= f) <|> (ys >>= f) would not. But, > this > > In this case `(xs >>= f) <|> (ys >>= f)` will also be empty as far as > I can see... > > I'm also trying to make some sense out of this definition of > alternative for lists. For `Maybe` we also have a left biased > alternative, and despite this I find it quite useful... > > > isn't a law or anything, you could chalk it up as counter-intuitive, but > not > > disqualifying. > > > > On Fri, May 5, 2017 at 11:12 PM, Theodore Lief Gannon > > wrote: > >> > >> Fiddling around, I found myself wanting: > >> > >> coalesce :: [a] -> [a] -> [a] > >> -- or -- :: (Foldable t) => t a -> t a -> t a > >> coalesce a b = if null a then b else a > >> > >> I expected this to be (<|>) (it is for Maybe!) but instead I find no > >> canonical implementation of it anywhere, and what seems like a useless > >> instance Alternative []. What's the rationale? > >> > >> _______________________________________________ > >> Haskell-Cafe mailing list > >> To (un)subscribe, modify options or view archives go to: > >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > >> Only members subscribed via the mailman list are allowed to post. > > > > > > > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From althainz at gmail.com Sun May 28 19:32:18 2017 From: althainz at gmail.com (Peter Althainz) Date: Sun, 28 May 2017 21:32:18 +0200 Subject: [Haskell-cafe] =?utf-8?q?Ralf_L=C3=A4mmel_gives_a_talk_at_Haskell?= =?utf-8?q?_User_Group_-_Frankfurt=2C_21=2E6=2E17?= Message-ID: Dear All, we are happy to have Ralf Lämmel in Frankfurt, talking about: "An interpreter for every season", targeted at a Haskell-friendly audience. https://www.meetup.com/de-DE/Frankfurt-Haskell-User-Group/events/240346167 regards Peter From dennis.raddle at gmail.com Sun May 28 20:53:22 2017 From: dennis.raddle at gmail.com (Dennis Raddle) Date: Sun, 28 May 2017 13:53:22 -0700 Subject: [Haskell-cafe] stack, git, directory structure Message-ID: I have a few basic questions about my project organization using stack. I'm going to have several executables and a hierarchical library. For instance, let's say I'm going to call my overall system "cac" (computer aided composition). I'll have imports like import Cac.Util import Cac.Search import Cac.Search.Algo1 -- some modules that assist things import XDoc import XDoc.Parse and so on. I'll have executables named 'foo', 'bar', etc. So would the following be correct? - call the directory where I put all stack packages $PROJ - call the top level of my specific project $PROJ/cac, which will have $PROJ/cac/cac.cabal - I'll have the following files and dirs: - modules: - $PROJ/cac/src/Cac.hs - $PROJ/cac/src/Cac/ - $PROJ/cac/src/Cac/Util.hs - $PROJ/cac/src/Cac/Search.hs - $PROJ/cac/src/Cac/Search/ - $PROJ/cac/src/XDoc.hs - $PROJ/cac/src/XDoc/ - $PROJ/cac/src/XDoc/Parse.hs - executables: - $PROJ/app/foo.hs - $PROJ/app/bar.hs Also, if I'm going to use git, would my .git/ directory be at $PROJ/cac/.git/ ? thanks D -------------- next part -------------- An HTML attachment was scrubbed... URL: From magnus at therning.org Sun May 28 21:22:33 2017 From: magnus at therning.org (Magnus Therning) Date: Sun, 28 May 2017 23:22:33 +0200 Subject: [Haskell-cafe] stack, git, directory structure In-Reply-To: References: Message-ID: <87h904fzhi.fsf@therning.org> Dennis Raddle writes: > I have a few basic questions about my project organization using stack. > > I'm going to have several executables and a hierarchical library. > > For instance, let's say I'm going to call my overall system "cac" (computer > aided composition). I'll have imports like > > import Cac.Util > import Cac.Search > import Cac.Search.Algo1 > -- some modules that assist things > import XDoc > import XDoc.Parse > > and so on. > > I'll have executables named 'foo', 'bar', etc. > > So would the following be correct? > > - call the directory where I put all stack packages $PROJ > > - call the top level of my specific project $PROJ/cac, which will have > $PROJ/cac/cac.cabal > > - I'll have the following files and dirs: > > - modules: > > - $PROJ/cac/src/Cac.hs > - $PROJ/cac/src/Cac/ > - $PROJ/cac/src/Cac/Util.hs > - $PROJ/cac/src/Cac/Search.hs > - $PROJ/cac/src/Cac/Search/ > - $PROJ/cac/src/XDoc.hs > - $PROJ/cac/src/XDoc/ > - $PROJ/cac/src/XDoc/Parse.hs > > - executables: > > - $PROJ/app/foo.hs > - $PROJ/app/bar.hs > > Also, if I'm going to use git, would my .git/ directory be at > $PROJ/cac/.git/ ? Depending a little on how tightly coupled lib and exes are I'd either put all into a single Cabal file: cac/ .git/... cac.cabal stack.yaml src/ Cac.hs Cac/ Util.hs ... app/ foo.hs bar.hs Or lib and exes in separate folders: $PROJ/ .git/... stack.yaml cac/ cac.cabal src/ Cac.hs Cac/ Util.hs ... app/ app.cabal foo.hs bar.hs Or maybe even each exe into its own folder. /M -- Magnus Therning OpenPGP: 0x927912051716CE39 email: magnus at therning.org jabber: magnus at therning.org twitter: magthe http://therning.org/magnus Computer Science: "In low-level languages like C" Computer Engineering: "In high-level languages like C" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From dennis.raddle at gmail.com Sun May 28 21:44:34 2017 From: dennis.raddle at gmail.com (Dennis Raddle) Date: Sun, 28 May 2017 14:44:34 -0700 Subject: [Haskell-cafe] stack, git, directory structure In-Reply-To: References: Message-ID: I got a private reply which helps but it made me think of another question. In the stack demo, there's one executable 'helloworld-exe' which is compiled from app/Main.hs. If I'm going to have several executables, what do I call the source files, and how do I control the file name of the executable that gets built? Thanks, D ​ -------------- next part -------------- An HTML attachment was scrubbed... URL: From plredmond at gmail.com Mon May 29 06:49:11 2017 From: plredmond at gmail.com (Patrick Redmond) Date: Mon, 29 May 2017 06:49:11 +0000 Subject: [Haskell-cafe] stack, git, directory structure In-Reply-To: References: Message-ID: You can name the source files whatever you like, and you can associate them with your desired ececutable names in the cabal file. Eg. In a cabal file: ... executable zshhs main-is: ZshClone.hs hs-source-dirs: src ... Where "zshhs" is the desired binary output name, and the directory containing this cabal file also contains "src/ZshClone.hs" with your main function. On Sun, May 28, 2017 at 14:46 Dennis Raddle wrote: > I got a private reply which helps but it made me think of another question. > > In the stack demo, there's one executable 'helloworld-exe' which is > compiled from app/Main.hs. > > If I'm going to have several executables, what do I call the source files, > and how do I control the file name of the executable that gets built? > > Thanks, > D > > ​ > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From P.Achten at cs.ru.nl Mon May 29 07:18:43 2017 From: P.Achten at cs.ru.nl (Peter Achten) Date: Mon, 29 May 2017 09:18:43 +0200 Subject: [Haskell-cafe] Call for participation: Trends in Functional Programming, 19-21 june 2017, University of Kent, Canterbury Message-ID: ----------------------------- C A L L F O R P A R T I C I P A T I O N ----------------------------- ======== TFP 2017 =========== 18th Symposium on Trends in Functional Programming 19-21 June, 2017 University of Kent, Canterbury https://www.cs.kent.ac.uk/events/tfp17/index.html The symposium on Trends in Functional Programming (TFP) is an international forum for researchers with interests in all aspects of functional programming, taking a broad view of current and future trends in the area. It aspires to be a lively environment for presenting the latest research results, and other contributions (see below). Authors of draft papers will be invited to submit revised papers based on the feedback receive at the symposium. A post-symposium refereeing process will then select a subset of these articles for formal publication. TFP 2017 will be the main event of a pair of functional programming events. TFP 2017 will be accompanied by the International Workshop on Trends in Functional Programming in Education (TFPIE), which will take place on 22 June. The TFP symposium is the heir of the successful series of Scottish Functional Programming Workshops. Previous TFP symposia were held in * Edinburgh (Scotland) in 2003; * Munich (Germany) in 2004; * Tallinn (Estonia) in 2005; * Nottingham (UK) in 2006; * New York (USA) in 2007; * Nijmegen (The Netherlands) in 2008; * Komarno (Slovakia) in 2009; * Oklahoma (USA) in 2010; * Madrid (Spain) in 2011; * St. Andrews (UK) in 2012; * Provo (Utah, USA) in 2013; * Soesterberg (The Netherlands) in 2014; * Inria Sophia-Antipolis (France) in 2015; * and Maryland (USA) in 2016. For further general information about TFP please see the TFP homepage. (http://www.tifp.org/). == SCOPE == The symposium recognizes that new trends may arise through various routes. As part of the Symposium's focus on trends we therefore identify the following five article categories. High-quality articles are solicited in any of these categories: Research Articles: leading-edge, previously unpublished research work Position Articles: on what new trends should or should not be Project Articles: descriptions of recently started new projects Evaluation Articles: what lessons can be drawn from a finished project Overview Articles: summarizing work with respect to a trendy subject Articles must be original and not simultaneously submitted for publication to any other forum. They may consider any aspect of functional programming: theoretical, implementation-oriented, or experience-oriented. Applications of functional programming techniques to other languages are also within the scope of the symposium. Topics suitable for the symposium include, but are not limited to: Functional programming and multicore/manycore computing Functional programming in the cloud High performance functional computing Extra-functional (behavioural) properties of functional programs Dependently typed functional programming Validation and verification of functional programs Debugging and profiling for functional languages Functional programming in different application areas: security, mobility, telecommunications applications, embedded systems, global computing, grids, etc. Interoperability with imperative programming languages Novel memory management techniques Program analysis and transformation techniques Empirical performance studies Abstract/virtual machines and compilers for functional languages (Embedded) domain specific languages New implementation strategies Any new emerging trend in the functional programming area If you are in doubt on whether your article is within the scope of TFP, please contact the TFP 2017 program chairs, Scott Owens and Meng Wang. == BEST PAPER AWARDS == To reward excellent contributions, TFP awards a prize for the best paper accepted for the formal proceedings. TFP traditionally pays special attention to research students, acknowledging that students are almost by definition part of new subject trends. A student paper is one for which the authors state that the paper is mainly the work of students, the students are listed as first authors, and a student would present the paper. A prize for the best student paper is awarded each year. In both cases, it is the PC of TFP that awards the prize. In case the best paper happens to be a student paper, that paper will then receive both prizes. == PAPER SUBMISSIONS == Acceptance of articles for presentation at the symposium is based on a lightweight peer review process of extended abstracts (4 to 10 pages in length) or full papers (20 pages). The submission must clearly indicate which category it belongs to: research, position, project, evaluation, or overview paper. It should also indicate which authors are research students, and whether the main author(s) are students. A draft paper for which ALL authors are students will receive additional feedback by one of the PC members shortly after the symposium has taken place. We use EasyChair for the refereeing process. Papers must be submitted at: https://easychair.org/conferences/?conf=tfp17 Papers must be written in English, and written using the LNCS style. For more information about formatting please consult the Springer LNCS web site: http://www.springer.com/computer/lncs?SGWID=0-164-6-793341-0 == INVITED SPEAKERS == Conor McBride University of Strathclyde (UK) Cătălin Hriţcu INRIA Paris (FR) == IMPORTANT DATES == Submission of draft papers: 5 May, 2017 Notification: 12 May, 2017 Registration: 11 June, 2017 TFP Symposium: 19-21 June, 2017 Student papers feedback: 29 June, 2017 Submission for formal review: 2 August, 2017 Notification of acceptance: 3 November, 2017 Camera ready paper: 2 December, 2017 == PROGRAM COMMITTEE == Co-Chairs Meng Wang University of Kent (UK) Scott Owens University of Kent (UK) PC Jeremy Yallop University of Cambridge (UK) Nicolas Wu University of Bristol (UK) Laura Castro University of A Coruña (ES) Gabriel Scherer Northeastern University (US) Edwin Brady University of St Andrews (UK) Janis Voigtländer Radboud University Nijmegen (NL) Peter Achten Radboud University Nijmegen (NL) Tom Schrijvers KU Leuven (BE) Matthew Fluet Rochester Institute of Technology (US) Mauro Jaskelioff CIFASIS/Universidad Nacional de Rosario (AG) Patricia Johann Appalachian State University (US) Bruno Oliveira The University of Hong Kong (HK) Rita Loogen Philipps-Universität Marburg (GE) David Van Horn University of Marylan (US) Soichiro Hidaka Hosei University (JP) Michał Pałka Chalmers University of Technology (SE) Sandrine Blazy University of Rennes 1 - IRISA (FR) From oleg at okmij.org Mon May 29 13:47:56 2017 From: oleg at okmij.org (Oleg) Date: Mon, 29 May 2017 22:47:56 +0900 Subject: [Haskell-cafe] A new type of newtype --- Type-level instance diversification and resolution (tl; dr) Message-ID: <20170529134756.GA3866@Magus.localnet> The idea of adding a label (`resolver') is very old. Here is the examples of how far you can take it: http://okmij.org/ftp/Haskell/TypeClass.html#Haskell1 We can represent all of Haskell98 classes plus functional dependencies with only one, predefined type class. From bneijt at gmail.com Mon May 29 14:40:01 2017 From: bneijt at gmail.com (Bram Neijt) Date: Mon, 29 May 2017 16:40:01 +0200 Subject: [Haskell-cafe] Haskell performance when it comes to regex? In-Reply-To: <1887CACF-C62A-4174-AE18-3DFFDD2882CC@regex.uk> References: <019C1A5D-9053-4DB1-A3C4-3E2856784A7E@gmail.com> <1887CACF-C62A-4174-AE18-3DFFDD2882CC@regex.uk> Message-ID: Hi Chris, Thank you for looking into this and thank you for your pull-request. I moved the "=~" outside of the map and that makes the whole thing a huge amount faster. Seems my assumption that =~ would memoise the regex creation (I read that in a post on regex in Haskell[1]) The 80% diff is now gone, the Python code was everything without the leveldb stuff (but still, compiling the regexes every time, so it seemed like a valid comparison at the time), see attachment for code. Thank you all for your help! Bram [1] http://www.serpentine.com/blog/2007/02/27/a-haskell-regular-expression-tutorial/ On Sun, May 28, 2017 at 2:22 PM, Chris Dornan wrote: > Hi Bram, > > > > Sorry for being a bit late to this -- I have been on the road. > > > > I have switched over you example to pre-compile the REs and use ByteString > and can see 13x speedup on scan and a 9x speedup on mapping. Curiously, > nearly all of that speedup seems to be gained by lifting the RE compilation > out of the loop but I am pretty sure there are gains to be had from > re-writing the loops. > > > > Do you have the Python code that was performing 80x better? > > > > Chris > > > > > > From: Alfredo Di Napoli > Date: Monday, 22 May 2017 at 08:48 > To: Bram Neijt > Cc: Станислав Черничкин , haskell-cafe > , Chris Dornan > Subject: Re: [Haskell-cafe] Haskell performance when it comes to regex? > > > > Hi Bram, > > > > you might be interested in the “regex” package from my colleague Chris > Dornan: > > > > http://regex.uk/ > > > > I know some proper performance work still needs to be done, but I would be > curious to hear your experience report ;) > > > > Alfredo > > > > On 19 May 2017 at 18:52, Bram Neijt wrote: > > Thank you! > > I already changed to Text instead, but I thought the regex was already > memoized by GHC, so that should not be a problem. > > I'm trying regex-applicative now, maybe that will help, but it takes > some time to figure out the syntax. I'll also try to see if > precompilation helps. > > Greetings, > > Bram > > > > > On Fri, May 19, 2017 at 1:17 PM, Станислав Черничкин > wrote: >> Try to use Text or ByteString instead of strings. Try to use compile and >> execute methods >> >> (http://hackage.haskell.org/package/regex-tdfa-1.2.1/docs/Text-Regex-TDFA-ByteString.html), >> make sure regex get compiled once. >> >> 2017-05-16 12:12 GMT+03:00 Bram Neijt : >>> >>> Dear reader, >>> >>> I decided to do a little project which is a simple search and replace >>> program for large text files. >>> >>> Written in Haskell, it does a few different regex matches on each line >>> and stores them in a leveldb key-value store to create a >>> consistent/reviewable search-replace index. It should provide for some >>> simple/brute-force anonymization of data and therefore I called it >>> hanon (sorry, could not think of a better name). >>> >>> https://github.com/BigDataRepublic/hanon >>> >>> The code works, but I've done some benchmarking to compare it with >>> Python and the code is about 80x slower then doing the same thing in >>> Python, making it useless for larger data files. >>> >>> I'm obviously doing something wrong. >>> >>> Could you give me tips on improving the performance of this code? >>> Probably mainly looking at >>> >>> https://github.com/BigDataRepublic/hanon/blob/master/src/Mapper.hs >>> >>> where the regex code lives? >>> >>> Greetings, >>> >>> Bram >>> _______________________________________________ >>> Haskell-Cafe mailing list >>> To (un)subscribe, modify options or view archives go to: >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >>> Only members subscribed via the mailman list are allowed to post. >> >> >> >> >> -- >> Sincerely, Stanislav Chernichkin. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > > -------------- next part -------------- A non-text attachment was scrubbed... Name: hanon.py Type: text/x-python Size: 1107 bytes Desc: not available URL: From chris at chrisdornan.com Mon May 29 19:53:56 2017 From: chris at chrisdornan.com (Chris Dornan) Date: Mon, 29 May 2017 20:53:56 +0100 Subject: [Haskell-cafe] Haskell performance when it comes to regex? In-Reply-To: References: <019C1A5D-9053-4DB1-A3C4-3E2856784A7E@gmail.com> <1887CACF-C62A-4174-AE18-3DFFDD2882CC@regex.uk> Message-ID: <3B9D23EE-8BCF-4A14-A5F9-E611FF3987E1@chrisdornan.com> Thanks Bram, There is correction in the comments to that Bryan O’Sullivan regex blog post by Chris Kuklewicz, the author of the regex packages: > You wrote: > > There’s normally no need to compile regular expression > > patterns. A pattern will be compiled the first time it’s used, > > and your Haskell runtime should memoise the compiled > > representation for you. > > Which is wrong. If you use =~ then the regexp is compiled with makeRegex and probably not cached. If you need to cache the compiled form then you need to use makeRegex and hold > onto the result and then use match separately (and matchM for =~~). (http://www.serpentine.com/blog/2007/02/27/a-haskell-regular-expression-tutorial/comment-page-1/#comment-22241) Pure library function are rarely memoised in Haskell because memorisation requires side effects to achieve transparently. I made four main things to optimise ‘hanon’ in my own ‘annie’ experimental Fork after profiling it: * I pre-compiled the REs (this accounted for most of the improvement); * as working with Strings are generally slow and ByteStrings just as convenient here, I converted everything to work with ByteString (though given your UTF8, requirements, Text might be more appropriate); * I switched from Text.Regex.TDFA to Text.Regex.PCRE (as I think you observed, judging by your commit messages), it seems to be somewhat faster, at lease for these relatively small data sets; * I combined all of the highlighter REs into a single RE of alternatives (using a function, leaving the ‘inputPaths’ organisation intact) as the multi-pass approach looked like it would be slower but also because it seemed to avoid some problems with overlapping REs. With these changes I saw a ~20x speedup over the ‘hanon’ source code (committed to master on 2017-05-16). The python code is ~4x faster than this on your sample ‘hello’ data set (which lines up with your reported 80x differential), though it only appears to identify the things to be anonymised in the input file, without carrying out any anonymisation. You can see my WIP here: https://github.com/cdornan/annie. (A warning, the main application wit all of the above changes has been rewritten, though there are variants of the original with the REs being precompiled and the ability to switch between String and ByteString for comparison purposes. It hasn’t been properly documented yet and remains WIP.) Chris On 29/05/2017, 15:40, "Bram Neijt" wrote: Hi Chris, Thank you for looking into this and thank you for your pull-request. I moved the "=~" outside of the map and that makes the whole thing a huge amount faster. Seems my assumption that =~ would memoise the regex creation (I read that in a post on regex in Haskell[1]) The 80% diff is now gone, the Python code was everything without the leveldb stuff (but still, compiling the regexes every time, so it seemed like a valid comparison at the time), see attachment for code. Thank you all for your help! Bram [1] http://www.serpentine.com/blog/2007/02/27/a-haskell-regular-expression-tutorial/ On Sun, May 28, 2017 at 2:22 PM, Chris Dornan wrote: > Hi Bram, > > > > Sorry for being a bit late to this -- I have been on the road. > > > > I have switched over you example to pre-compile the REs and use ByteString > and can see 13x speedup on scan and a 9x speedup on mapping. Curiously, > nearly all of that speedup seems to be gained by lifting the RE compilation > out of the loop but I am pretty sure there are gains to be had from > re-writing the loops. > > > > Do you have the Python code that was performing 80x better? > > > > Chris > > > > > > From: Alfredo Di Napoli > Date: Monday, 22 May 2017 at 08:48 > To: Bram Neijt > Cc: Станислав Черничкин , haskell-cafe > , Chris Dornan > Subject: Re: [Haskell-cafe] Haskell performance when it comes to regex? > > > > Hi Bram, > > > > you might be interested in the “regex” package from my colleague Chris > Dornan: > > > > http://regex.uk/ > > > > I know some proper performance work still needs to be done, but I would be > curious to hear your experience report ;) > > > > Alfredo > > > > On 19 May 2017 at 18:52, Bram Neijt wrote: > > Thank you! > > I already changed to Text instead, but I thought the regex was already > memoized by GHC, so that should not be a problem. > > I'm trying regex-applicative now, maybe that will help, but it takes > some time to figure out the syntax. I'll also try to see if > precompilation helps. > > Greetings, > > Bram > > > > > On Fri, May 19, 2017 at 1:17 PM, Станислав Черничкин > wrote: >> Try to use Text or ByteString instead of strings. Try to use compile and >> execute methods >> >> (http://hackage.haskell.org/package/regex-tdfa-1.2.1/docs/Text-Regex-TDFA-ByteString.html), >> make sure regex get compiled once. >> >> 2017-05-16 12:12 GMT+03:00 Bram Neijt : >>> >>> Dear reader, >>> >>> I decided to do a little project which is a simple search and replace >>> program for large text files. >>> >>> Written in Haskell, it does a few different regex matches on each line >>> and stores them in a leveldb key-value store to create a >>> consistent/reviewable search-replace index. It should provide for some >>> simple/brute-force anonymization of data and therefore I called it >>> hanon (sorry, could not think of a better name). >>> >>> https://github.com/BigDataRepublic/hanon >>> >>> The code works, but I've done some benchmarking to compare it with >>> Python and the code is about 80x slower then doing the same thing in >>> Python, making it useless for larger data files. >>> >>> I'm obviously doing something wrong. >>> >>> Could you give me tips on improving the performance of this code? >>> Probably mainly looking at >>> >>> https://github.com/BigDataRepublic/hanon/blob/master/src/Mapper.hs >>> >>> where the regex code lives? >>> >>> Greetings, >>> >>> Bram >>> _______________________________________________ >>> Haskell-Cafe mailing list >>> To (un)subscribe, modify options or view archives go to: >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >>> Only members subscribed via the mailman list are allowed to post. >> >> >> >> >> -- >> Sincerely, Stanislav Chernichkin. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > > From allbery.b at gmail.com Mon May 29 20:48:53 2017 From: allbery.b at gmail.com (Brandon Allbery) Date: Mon, 29 May 2017 16:48:53 -0400 Subject: [Haskell-cafe] Haskell performance when it comes to regex? In-Reply-To: <3B9D23EE-8BCF-4A14-A5F9-E611FF3987E1@chrisdornan.com> References: <019C1A5D-9053-4DB1-A3C4-3E2856784A7E@gmail.com> <1887CACF-C62A-4174-AE18-3DFFDD2882CC@regex.uk> <3B9D23EE-8BCF-4A14-A5F9-E611FF3987E1@chrisdornan.com> Message-ID: On Mon, May 29, 2017 at 3:53 PM, Chris Dornan wrote: > * I switched from Text.Regex.TDFA to Text.Regex.PCRE (as I think you > observed, judging by your commit messages), it seems to be somewhat > faster, at lease for these relatively small data sets; > TDFA is pure Haskell and mostly exists for when you can't be certain that a faster C binding will support UTF8 (most POSIX regex implementations do not, and PCRE only does so if someone built it with UTF8 support). When it's usable, the C bindings will almost always be faster. -- brandon s allbery kf8nh sine nomine associates allbery.b at gmail.com ballbery at sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net -------------- next part -------------- An HTML attachment was scrubbed... URL: From mail at joachim-breitner.de Tue May 30 00:52:21 2017 From: mail at joachim-breitner.de (Joachim Breitner) Date: Mon, 29 May 2017 20:52:21 -0400 Subject: [Haskell-cafe] A new type of newtype --- Type-level instance diversification and resolution (tl; dr) In-Reply-To: <1412a619-9c69-ecea-2834-edd98ce13a2d@vex.net> References: <1412a619-9c69-ecea-2834-edd98ce13a2d@vex.net> Message-ID: <1496105541.29421.3.camel@joachim-breitner.de> Hi, Am Donnerstag, den 25.05.2017, 21:26 -0400 schrieb Albert Y. C. Lai: > class MyOrd (resolver :: k) a where >      mycmp :: p resolver -> a -> a -> Ordering neat! Have you considered using Symbol (i.e. type-level strings) instead of an arbitrary kind k? Would that have any advantages or disadvantages? I wonder because of > I thank jadrian from IRC for proposing "named instance": > > > so instead of "instance Num n => Monoid (Sum n) where" we'd write > > e.g.  > > "instance Sum of Num n => Monoid n where"   and use it as > > "Sum.mempty" and “names” are more often than not “strings”. But then, arbitary kinds are more flexible, e.g. when you want to parametrize the resolver: data PointWise r instance MyOrd r a -> MyOrd (PointWise r) [a] Greetings, Joachim -- Joachim “nomeata” Breitner   mail at joachim-breitner.de • https://www.joachim-breitner.de/   XMPP: nomeata at joachim-breitner.de • OpenPGP-Key: 0xF0FBF51F   Debian Developer: nomeata at debian.org -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: This is a digitally signed message part URL: From saurabhnanda at gmail.com Tue May 30 02:16:27 2017 From: saurabhnanda at gmail.com (Saurabh Nanda) Date: Tue, 30 May 2017 07:46:27 +0530 Subject: [Haskell-cafe] Haskell performance when it comes to regex? In-Reply-To: References: <019C1A5D-9053-4DB1-A3C4-3E2856784A7E@gmail.com> <1887CACF-C62A-4174-AE18-3DFFDD2882CC@regex.uk> <3B9D23EE-8BCF-4A14-A5F9-E611FF3987E1@chrisdornan.com> Message-ID: Sorry for jumping in. IIUC the largest speedup was delivered by moving a reger compilation expression out of a loop. If the regex compilation is a pure function, being passed the exact same arguments during every invocation of the loop, shouldn't the compiler be smart enough to optimise it? Isnt this the basic premise of pure FP? On 30-May-2017 2:20 AM, "Brandon Allbery" wrote: On Mon, May 29, 2017 at 3:53 PM, Chris Dornan wrote: > * I switched from Text.Regex.TDFA to Text.Regex.PCRE (as I think you > observed, judging by your commit messages), it seems to be somewhat > faster, at lease for these relatively small data sets; > TDFA is pure Haskell and mostly exists for when you can't be certain that a faster C binding will support UTF8 (most POSIX regex implementations do not, and PCRE only does so if someone built it with UTF8 support). When it's usable, the C bindings will almost always be faster. -- brandon s allbery kf8nh sine nomine associates allbery.b at gmail.com ballbery at sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From qdunkan at gmail.com Tue May 30 04:48:57 2017 From: qdunkan at gmail.com (Evan Laforge) Date: Mon, 29 May 2017 21:48:57 -0700 Subject: [Haskell-cafe] Haskell performance when it comes to regex? In-Reply-To: References: <019C1A5D-9053-4DB1-A3C4-3E2856784A7E@gmail.com> <1887CACF-C62A-4174-AE18-3DFFDD2882CC@regex.uk> Message-ID: On Mon, May 29, 2017 at 7:40 AM, Bram Neijt wrote: > The 80% diff is now gone, the Python code was everything without the > leveldb stuff (but still, compiling the regexes every time, so it > seemed like a valid comparison at the time), see attachment for code. Python's re module has an internal cache, so it probably wasn't compiling every time. From dennis.raddle at gmail.com Tue May 30 04:50:49 2017 From: dennis.raddle at gmail.com (Dennis Raddle) Date: Mon, 29 May 2017 21:50:49 -0700 Subject: [Haskell-cafe] data mining, or something like it Message-ID: I have a general computer science question first, and then I will ask if Haskell might be helpful for this. I'm researching "algorithmic music composition," the construction of musical compositions through choices made my algorithms. No piece of music is ever 100% human-composed or 100% algorithmic -- so to be more clear, I'm interested in researching "musical fitness functions" that produce good results when searching the music space. Anything the computer composes will be listened to by me, and only the most promising fitness functions will be explored in greater depth. So my general question is about the following idea -- So in the course of generating lots of musical examples, and rating them as "good" or "bad," I'll end up with a database that can perhaps be "mined" for new fitness functions. I would start with a question. A random example of a question would be "is there a pattern in the density of dissonance, such that more dissonance in certain places in the composition tends to make it better (or worse)?" I would suspect, out of pure intuition, that it does, but I may not know the exact details. For instance, I might not know if dissonance matters more in certain places within a measure. So I could code up something that looks for patterns among the good and bad musical examples in my database to see if it can find something specific. So is this called "data mining" or something else? Second, are there any Haskell libraries that can help with this task? Thanks, D -------------- next part -------------- An HTML attachment was scrubbed... URL: From mjt464 at gmail.com Tue May 30 06:57:44 2017 From: mjt464 at gmail.com (mike thomas) Date: Tue, 30 May 2017 16:57:44 +1000 Subject: [Haskell-cafe] data mining, or something like it In-Reply-To: References: Message-ID: Hi Dennis. I can't help you with an up to date data mining definition, but it sounds like you're in the ball park. Regarding your musical plans, try: http://donyaquick.com/kulitta/ And I think Paul Hudak did work in that general area years ago too, perhaps at Yale. Good luck. Mike. On 30 May 2017 2:53 pm, "Dennis Raddle" wrote: > I have a general computer science question first, and then I will ask if > Haskell might be helpful for this. > > I'm researching "algorithmic music composition," the construction of > musical compositions through choices made my algorithms. No piece of music > is ever 100% human-composed or 100% algorithmic -- so to be more clear, I'm > interested in researching "musical fitness functions" that produce good > results when searching the music space. Anything the computer composes will > be listened to by me, and only the most promising fitness functions will be > explored in greater depth. > > So my general question is about the following idea -- > > So in the course of generating lots of musical examples, and rating them > as "good" or "bad," I'll end up with a database that can perhaps be "mined" > for new fitness functions. I would start with a question. A random example > of a question would be "is there a pattern in the density of dissonance, > such that more dissonance in certain places in the composition tends to > make it better (or worse)?" I would suspect, out of pure intuition, that it > does, but I may not know the exact details. For instance, I might not know > if dissonance matters more in certain places within a measure. So I could > code up something that looks for patterns among the good and bad musical > examples in my database to see if it can find something specific. > > So is this called "data mining" or something else? > > Second, are there any Haskell libraries that can help with this task? > > Thanks, > D > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From chris at chrisdornan.com Tue May 30 10:08:08 2017 From: chris at chrisdornan.com (Chris Dornan) Date: Tue, 30 May 2017 11:08:08 +0100 Subject: [Haskell-cafe] Haskell performance when it comes to regex? In-Reply-To: <9D847CC2-DF79-4AD6-92FE-BF98D5FAAAF2@gmail.com> References: <019C1A5D-9053-4DB1-A3C4-3E2856784A7E@gmail.com> <1887CACF-C62A-4174-AE18-3DFFDD2882CC@regex.uk> <3B9D23EE-8BCF-4A14-A5F9-E611FF3987E1@chrisdornan.com> <9D847CC2-DF79-4AD6-92FE-BF98D5FAAAF2@gmail.com> Message-ID: <45720477-194E-4E73-BA45-06FC048D2C5B@regex.uk> Brandon Allbery allbery.b at gmail.com: > TDFA is pure Haskell and mostly exists for when you can't be certain that a faster C binding will support UTF8 > (most POSIX regex implementations do not, and PCRE only does so if someone built it with UTF8 support). > When it's usable, the C bindings will almost always be faster. I think we are in agreement, though I would generally recommend TDFA, unless you need the highest performance (as in this case) or Perl-style REs. But then again I like my REs plain and simple (and Posix) and packages with as few external dependencies as possible. Chris From dennis.raddle at gmail.com Tue May 30 10:18:00 2017 From: dennis.raddle at gmail.com (Dennis Raddle) Date: Tue, 30 May 2017 03:18:00 -0700 Subject: [Haskell-cafe] data mining, or something like it In-Reply-To: References: Message-ID: Just to be clear, I am looking for Haskell code or libraries that implement general strategies for data mining, if there is such a thing. I'm not looking for music-related Haskell code, as the goal of my project is to learn about algorithms that make music with features similar to my own style as a traditional composer, and that will require testing a lot of possibilities, maybe very different ways of going about it. D -------------- next part -------------- An HTML attachment was scrubbed... URL: From jo at durchholz.org Tue May 30 10:27:04 2017 From: jo at durchholz.org (Joachim Durchholz) Date: Tue, 30 May 2017 12:27:04 +0200 Subject: [Haskell-cafe] Haskell performance when it comes to regex? In-Reply-To: <45720477-194E-4E73-BA45-06FC048D2C5B@regex.uk> References: <019C1A5D-9053-4DB1-A3C4-3E2856784A7E@gmail.com> <1887CACF-C62A-4174-AE18-3DFFDD2882CC@regex.uk> <3B9D23EE-8BCF-4A14-A5F9-E611FF3987E1@chrisdornan.com> <9D847CC2-DF79-4AD6-92FE-BF98D5FAAAF2@gmail.com> <45720477-194E-4E73-BA45-06FC048D2C5B@regex.uk> Message-ID: <76497a8d-b4cf-dc8b-64a2-c2403224abfe@durchholz.org> Am 30.05.2017 um 12:08 schrieb Chris Dornan: > I would generally recommend TDFA, unless you need the highest performance > (as in this case) or Perl-style REs. Just for the record: Be aware the PCRE isn't the fastest regex engine out there. It's generally good, but (a) it's doing backtracking which can make it exponentially slow, and (b) since Perl regexes have so many features, the PCRE engine cannot apply all optimizations that a highly optimized RE engine could. As always, if speed is an issue, assumptions and word of mouth need to be verified using benchmarks. From code at funwithsoftware.org Tue May 30 18:13:11 2017 From: code at funwithsoftware.org (Patrick Pelletier) Date: Tue, 30 May 2017 11:13:11 -0700 Subject: [Haskell-cafe] listing include files in a cabal file Message-ID: <363d9a2e-8543-4d25-030f-81d180eaf6f2@funwithsoftware.org> I have some C code in my Cabal package, consisting of both *.c and *.h files. Obviously, the *.c files get listed in "c-sources". But I'm trying to figure out where to list the *.h files. Right now, I'm not listing them anywhere, and my package compiles just fine. According to the Cabal users guide, there is an "includes" field and an "install-includes" field. The "includes" field seems to only be relevant when compiling via C. And even when compiling via C, wouldn't the include already be picked up when it is part of the foreign declaration, e. g.: foreign import ccall unsafe "tmr_tag_data.h TMR_bytesToHex" c_TMR_bytesToHex :: Ptr Word8 -> Word32 -> CString -> IO () As for the "install-includes" field, I don't think my header files would need to be installed, because they're internal to my package. The package's interface is entirely in Haskell. Should I just put my include files in "extra-source-files", so they get added to the package, but otherwise aren't treated specially? Or should I be using "includes" and/or "install-includes"? Thanks, --Patrick From rae at cs.brynmawr.edu Tue May 30 18:43:17 2017 From: rae at cs.brynmawr.edu (Richard Eisenberg) Date: Tue, 30 May 2017 14:43:17 -0400 Subject: [Haskell-cafe] Haskell Implementors' Workshop Call for Talks Message-ID: <89244F5C-058B-426D-84A4-4A4D62C2E880@cs.brynmawr.edu> Call for Contributions ACM SIGPLAN Haskell Implementors' Workshop http://icfp17.sigplan.org/track/hiw-2017 Oxford, UK, 9 September, 2017 Co-located with ICFP 2017 http://www.icfpconference.org/icfp2017/ Important dates --------------- Proposal Deadline: Thursday, 6 July, 2017 Notification: Thursday, 20 July, 2017 Workshop: Saturday, 9 September, 2017 The 9th Haskell Implementors' Workshop is to be held alongside ICFP 2017 this year in Oxford. It is a forum for people involved in the design and development of Haskell implementations, tools, libraries, and supporting infrastructure, to share their work and discuss future directions and collaborations with others. Talks and/or demos are proposed by submitting an abstract, and selected by a small program committee. There will be no published proceedings. The workshop will be informal and interactive, with open spaces in the timetable and room for ad-hoc discussion, demos, and impromptu short talks. Scope and target audience ------------------------- It is important to distinguish the Haskell Implementors' Workshop from the Haskell Symposium which is also co-located with ICFP 2017. The Haskell Symposium is for the publication of Haskell-related research. In contrast, the Haskell Implementors' Workshop will have no proceedings -- although we will aim to make talk videos, slides and presented data available with the consent of the speakers. The Implementors' Workshop is an ideal place to describe a Haskell extension, describe works-in-progress, demo a new Haskell-related tool, or even propose future lines of Haskell development. Members of the wider Haskell community encouraged to attend the workshop -- we need your feedback to keep the Haskell ecosystem thriving. Students working with Haskell are specially encouraged to share their work. The scope covers any of the following topics. There may be some topics that people feel we've missed, so by all means submit a proposal even if it doesn't fit exactly into one of these buckets: * Compilation techniques * Language features and extensions * Type system implementation * Concurrency and parallelism: language design and implementation * Performance, optimisation and benchmarking * Virtual machines and run-time systems * Libraries and tools for development or deployment Talks ----- We invite proposals from potential speakers for talks and demonstrations. We are aiming for 20-minute talks with 5 minutes for questions and changeovers. We want to hear from people writing compilers, tools, or libraries, people with cool ideas for directions in which we should take the platform, proposals for new features to be implemented, and half-baked crazy ideas. Please submit a talk title and abstract of no more than 300 words. Submissions should be made via HotCRP. The website is: https://icfp-hiw17.hotcrp.com/ We will also have a lightning talks session which will be organised on the day. These talks will be 5-10 minutes, depending on available time. Suggested topics for lightning talks are to present a single idea, a work-in-progress project, a problem to intrigue and perplex Haskell implementors, or simply to ask for feedback and collaborators. Program Committee ----------------- * Richard A. Eisenberg -- chair (Bryn Mawr College) * Adam Gundry (Well-Typed) * Bartosz Nitka (Facebook) * Wren Romano (X, formerly Google[x]) * Alejandro Serrano Mena (Utrecht University) * Jan Stolarek (University of Edinburgh) Contact ------- * Richard A. Eisenberg From rae at cs.brynmawr.edu Tue May 30 19:43:30 2017 From: rae at cs.brynmawr.edu (Richard Eisenberg) Date: Tue, 30 May 2017 15:43:30 -0400 Subject: [Haskell-cafe] [ghc-proposals/cafe] Partially applied type families In-Reply-To: <5925328e.31b.5df7.29201@clear.net.nz> References: <5925328e.31b.5df7.29201@clear.net.nz> Message-ID: <5CFB4D28-5CD9-4F23-9082-E947D96ACABB@cs.brynmawr.edu> > On May 24, 2017, at 3:13 AM, Anthony Clayden wrote: > > Then I guess I remain to be convinced > of the value of dependent typing within Haskell. The existing dependently typed languages (I'm thinking of Coq, Adga, and Idris -- just not as familiar with F* and perhaps others) do type inference on a best-effort basis, with very little that I have found in the literature describing the type inference process. One of the major challenges of dependent types in Haskell is to continue Haskell's tradition of predictable, describable type inference. In other words, adding dependent types needn't take anything away from the fragment of Haskell you wish to work in. Indeed, the lack of injectivity for type families is the same kind of problem that exists in those other languages, so Haskell has already paid this price. > > I'd like term-level functions to be more like instances. > That is, with the equations distributed, see your example > below. > (Yes the set of equations must be coherent overall. > That's something the compiler can check for me.) I think it depends on the function. Some functions are defined by an ordered set of equations. Some (that is, class methods) are defined by an unordered set of equations, perhaps distributed across modules. Both models are useful. > > There was some doubt whether there could be a type-level > disequality test. And indeed this was hard! See "apartness". > >> ... [equality constraints and equality guards are] different, but I think the equality guard is > useless > > I see two main uses/benefits: > 1. avoids the need for non-linear patterns in the head Agreed that it would do this. But why is that important? > 2. visually points up the 'non-apartness' vs an, um. > "apartness guard" > > (When I was figuring out Andy A-M's 2013 example, > I rewrote the non-linear patterns with ~ guards, > so I could figure out the apartness guards > esp for the semi-apart instances. > I posted the later workings to your blog Somehow, this is more convincing. But I'm still not convinced on this point. Happily, you don't need to convince me -- put in the proposal what you like and then we can debate a concrete design. >> [except as a type-level "let", I suppose].) > > No, they're not doing that: > deliberately I don't allow guards > to introduce new type vars. They would work as "let", I think: > instance Either a a | a ~ SomethingBigAndUgly where ... Note that the `a` is not introduced in the guard. > Ok thanks, yes [TypeError] helps. > Nevertheless it seems disergonomic > to write an instance for a type-equal case, > even with a helpful error message; > when what you want is: no such instance. You could always view > instance TypeError ... => C Int Bool as sugar for > instance C Int Bool fails The first declaration isn't so bad, I think, that it warrants introducing new concrete syntax. > > What I can see will be awkward is backwards compatibility: > can a class/type family with guards > coexist with CTFs and with classes using overlap? Sure. There would be no problem with this. The new idea is just that: new. I don't see it as getting rid of anything we already have. Perhaps some day we could think about removing OverlappingInstances, but we certainly don't have to do that at the same time as introducing instance guards. (I do like that name, too.) > >> Next step: write a ghc-proposal. I'll support it. If I had >> the time, I'd even implement it. > > I'll have a crack at the proposal. Great. Thanks! Richard From rae at cs.brynmawr.edu Tue May 30 19:50:13 2017 From: rae at cs.brynmawr.edu (Richard Eisenberg) Date: Tue, 30 May 2017 15:50:13 -0400 Subject: [Haskell-cafe] [ghc-proposals/cafe] Partially applied type families In-Reply-To: References: <591a5528.271.3b05.31512@clear.net.nz> Message-ID: <63EA7C86-D447-4BD6-9CD4-56291E559131@cs.brynmawr.edu> > On May 24, 2017, at 3:57 AM, Alejandro Serrano Mena wrote: > > I would like to advise against this idea of apartness guards. I've tried myself some years ago, and I remember them being quite complicated to describe. The main problem is that apartness may end up introducing some sort of backtracking in the type checking process -- something completely undesirable. Furthermore, they make the work of the overlapping checks much harder. Do you recall an example of where things went wrong? It seems to me that GHC does this today. If I have > instance C (Maybe a) where ... > instance {-# OVERLAPPING #-} C (Maybe Int) where ... then GHC won't choose the first instance unless it knows that `a` is apart from Int. Indeed, it is possible to write a program that is accepted with only the first instance in scope but is rejected when the second one is, too. Under instance guards, this could be written > instance C (Maybe a) | a /~ Int where ... > instance C (Maybe Int) where ... and then both instances stand alone and make sense independent of one another. Richard -------------- next part -------------- An HTML attachment was scrubbed... URL: From dennis.raddle at gmail.com Wed May 31 02:39:18 2017 From: dennis.raddle at gmail.com (Dennis Raddle) Date: Tue, 30 May 2017 19:39:18 -0700 Subject: [Haskell-cafe] is 'stack ghci' really experimental? Message-ID: I noticed that the stack docs say 'stack ghci' is experimental. I assume it's a common need (certainly is for me) to interpret my code while developing. Is it safe to use 'stack ghci' or is there another way that is more robust? D -------------- next part -------------- An HTML attachment was scrubbed... URL: From anthony_clayden at clear.net.nz Wed May 31 04:31:30 2017 From: anthony_clayden at clear.net.nz (Anthony Clayden) Date: Wed, 31 May 2017 16:31:30 +1200 Subject: [Haskell-cafe] [ghc-proposals/cafe] Partially applied type families Message-ID: <592e4722.2a3.645c.14508@clear.net.nz> > On Tue May 30 19:43:30 UTC 2017, Richard Eisenberg wrote: > > On May 24, 2017, at 3:13 AM, Anthony Clayden wrote: > ... Some functions are defined by an ordered set of equations. > Some (that is, class methods) are defined by > an unordered set of equations, perhaps distributed across modules. > Both models are useful. Sure. Let a 100 schools of thought contend. >>> ... [equality constraints and equality guards are] >>> different, but I think the equality guard is useless >> I agree adds nothing over repeating the typevar. And I've already agreed the potential for confusion with (~) constraints. So noted. I'll include it in the proposal, where a wider audience can bikeshed. >> I see two main uses/benefits: >> 1. avoids the need for non-linear patterns in the head > > Agreed that it would do this. But why is that important? > I was in part thinking of your wondering-out-loud earlier in the Partially applied thread https://mail.haskell.org/pipermail/haskell-cafe/2017-May/127078.html If we want to part-apply a type Fun which has a non-linear lhs, how does that go with your case-equation style? Adapting that earlier example: > type family F a b where > F a a = () -- added an equation > F Int b = b > F a Bool = a would really mean > type F a b = case a of > _ -> case b of -- ?? _ match-all > a -> () -- ?? re-using typevar a > Int -> b > _ -> case b of > Bool -> a > _ -> F a b > > 2. visually points up the 'non-apartness' vs an, um. > > "apartness guard" > > > > (When I was figuring out Andy A-M's 2013 example, > > I rewrote the non-linear patterns with ~ guards, > > so I could figure out the apartness guards > > esp for the semi-apart instances. > > I posted the later workings to your blog > > Somehow, this is more convincing. But I'm still not > convinced on this point. Happily, you don't need to > convince me -- put in the proposal what you like and then > we can debate a concrete design. > > >> [except as a type-level "let", I suppose].) > > They would work as "let", I think: > > > instance Either a a | a ~ SomethingBigAndUgly where ... > > Note that the `a` is not introduced in the guard. Ah, OK. I get you. Equally that could be > instance Either a b | a ~ b, a ~ SomethingBigAndUgly where .. > > > Ok thanks, yes [TypeError] helps. > > Nevertheless it seems disergonomic > > to write an instance for a type-equal case, > > even with a helpful error message; > > when what you want is: no such instance. > > You could always view > > > instance TypeError ... => C Int Bool > > as sugar for > > > instance C Int Bool fails Yes I understand that. But no I don't want any instance. (Sugar on rotten fruit doesn't hide the smell.) There are (or at least used to be) all sorts of side-effects from there in effect being an instance that matched. > > What I can see will be awkward is backwards > > compatibility: can a class/type family with guards > > coexist with CTFs and with classes using overlap? > > Sure. There would be no problem with this. The new idea is > just that: new. I don't see it as getting rid of anything > we already have. Perhaps some day we could think about > removing OverlappingInstances, but we certainly don't have > to do that at the same time as introducing instance > guards. (I do like that name, too.) > OK. Perhaps you're seeing something I can't. To adapt your example from a parallel message, suppose: > module A > > class {-# INSTANCEGUARDS #-} C a where ... > instance C (Maybe a) | a /~ Int where ... > instance C (Maybe Int) where ... > > module B > -- knows nothing of InstanceGuards > import A > > instance {-# OVERLAPPABLE #-} C (Maybe Bool) where ... I want to reject that `(Maybe Bool)` instance. Even though it would legitimately be OVERLAPPABLE by (Maybe a) (that is, without the `a /~ Int` guard). Furthermore I might want a class to be InstanceGuarded, even though the instances I declare don't themselves need guards. (That is, I'm wanting to avoid 'future' overlaps in modules that import the class.) > > > > I'll have a crack at the proposal. > > Great. Thanks! (Likely I'll need some help with the protocols.) AntC From dennis.raddle at gmail.com Wed May 31 07:34:42 2017 From: dennis.raddle at gmail.com (Dennis Raddle) Date: Wed, 31 May 2017 00:34:42 -0700 Subject: [Haskell-cafe] is 'stack ghci' really experimental? In-Reply-To: References: Message-ID: Oh, I also wanted to ask about Haskell mode of Emacs and ghci. I have not tried to run ghci from within Emacs, but I can imagine doing so would provide an advantage. Does haskelll-mode parse line numbers in error messages and jump to them? And is it possible to run 'stack ghci' from within haskell-mode? Thanks D On Tue, May 30, 2017 at 7:39 PM, Dennis Raddle wrote: > I noticed that the stack docs say 'stack ghci' is experimental. I assume > it's a common need (certainly is for me) to interpret my code while > developing. Is it safe to use 'stack ghci' or is there another way that is > more robust? > D > -------------- next part -------------- An HTML attachment was scrubbed... URL: From adam at bergmark.nl Wed May 31 09:22:09 2017 From: adam at bergmark.nl (Adam Bergmark) Date: Wed, 31 May 2017 09:22:09 +0000 Subject: [Haskell-cafe] is 'stack ghci' really experimental? In-Reply-To: References: Message-ID: I'm sure stack ghci still has some quirks, but i've used it since the initial release without major problems. I'd recommend looking at intero mode for stack+emacs integration. On Wed, 31 May 2017 at 09:36, Dennis Raddle wrote: > Oh, I also wanted to ask about Haskell mode of Emacs and ghci. I have not > tried to run ghci from within Emacs, but I can imagine doing so would > provide an advantage. Does haskelll-mode parse line numbers in error > messages and jump to them? > > And is it possible to run 'stack ghci' from within haskell-mode? > > Thanks > D > > On Tue, May 30, 2017 at 7:39 PM, Dennis Raddle > wrote: > >> I noticed that the stack docs say 'stack ghci' is experimental. I assume >> it's a common need (certainly is for me) to interpret my code while >> developing. Is it safe to use 'stack ghci' or is there another way that is >> more robust? >> D >> > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From anthony_clayden at clear.net.nz Wed May 31 11:43:31 2017 From: anthony_clayden at clear.net.nz (Anthony Clayden) Date: Wed, 31 May 2017 23:43:31 +1200 Subject: [Haskell-cafe] Type-level GCD [Instance Chains] Message-ID: <592eac63.1cf.1ab4.10487@clear.net.nz> I'm re-reading the Instance Chains paper. http://dl.acm.org/citation.cfm?id=1863596 [2010, so before Type Families got off the ground] And wondering about some of [*] their motivating examples. [Disclaimer: with a view to writing up something I think is better.] Leaving aside the question of backtracking on instance non-match, would anybody write a type-level GCD like this? We have the usual type-level Naturals and Booleans: > {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, > OverlappingInstances, EmptyDataDecls #-} > > data Z; data S n > > data T; data F And then: > class Gcd m n p | m n → p --p=gcd(m,n) > instance Gcd m m m -- OVERLAPPABLE OK > instance (Lte n m T, Subt m n m', Gcd m' n p) > ⇒ Gcd m n p > instance (Lte n m F, Subt n m n', Gcd m n' p) > ⇒ Gcd m n p Those latter two instances overlap (heads are identical) in an irresolvable way. (They're trying to distinguish the `m > n` vs `m < n` cases.) The code is closely following how you might write with Integers, I guess. But I'm not convinced it's such a good approach for Peanos. Class Lte compares two Peanos, tells which is the larger. Class Subt subtracts one from the other. They're both traversing the (S (S (S ... Z...))) nesting. (And Subt needs a nasty kludge in case you're trying to subtract the larger: it returns Z.) I think these days (esp with TypeFamilies/Assoc types), I'd write those latter two instances with a case helper. And a discriminator type fun `Diff` that provides the absolute diff, and tells which param is smaller. But to keep in the same style, I'll put `Diff` as a class: > instance (Diff m n d, GcdCase d m n p) > => Gcd m n p -- single 'catch all' instance > > class GcdCase d m n p | d m n -> p > instance (Gcd d' n p) > => GcdCase (T, d') m n p > instance (Gcd m d' p) > => GcdCase (F, d') m n p > > class Diff m n d | m n -> d > instance Diff Z (S n') (T, S n') > instance Diff (S m') Z (F, S m') > instance (Diff m' n' d) => Diff (S m') (S n') d Seems to me the code is more succinct, and easier to follow. (And by the way doesn't need egregious overlaps.) [*] Actually, I'm dubious about all of their examples. More to follow ... AntC From jgbm at acm.org Wed May 31 14:19:55 2017 From: jgbm at acm.org (J. Garrett Morris) Date: Wed, 31 May 2017 15:19:55 +0100 Subject: [Haskell-cafe] Type-level GCD [Instance Chains] Message-ID: [Apologies for breaking threading...] On Wed May 31, Anthony Clayden wrote: > Leaving aside the question of backtracking on instance > non-match, > would anybody write a type-level GCD like this? Your question seems to be "would you use the standard recursive statement of Euclid's algorithm to demonstrate Euclid's algorithm?" This certainly seemed to be a reasonable idea in 2010. If your concern is efficiency, I suggest that not using Peano numerals at all is probably a more profitable direction. > (And Subt needs a nasty kludge in case you're trying to > subtract the larger: it returns Z.) What you call a nasty kludge, I call a standard operation on commutative monoids. [https://en.wikipedia.org/wiki/Monus] > I think these days (esp with TypeFamilies/Assoc types), You seem to be discovering that closed instance chains can be implemented by writing out truth tables. I discussed this transformation at length, and suggested that doing might make your code harder to write and to read, in my Haskell 2015 paper "Variations on Variants". Of course, you'll have an easier time of it if you limit yourself to only considering type-level definitions, and not the corresponding method definitions. But doing so rather misses the point of instance chains. /g -- Prosperum ac felix scelus virtus vocatur -- Seneca From evan at evanrutledgeborden.dreamhosters.com Wed May 31 15:44:01 2017 From: evan at evanrutledgeborden.dreamhosters.com (evan@evan-borden.com) Date: Wed, 31 May 2017 11:44:01 -0400 Subject: [Haskell-cafe] ANN: network-2.6.3.2 Message-ID: Announcing network-2.6.3.2 This release includes many improvements to documentation and infrastructure as well as a few API additions. As always a huge thank you to the network contributors. Version 2.6.3.2 * Zero memory of `sockaddr_un` if abstract socket [#220](https://github.com/haskell/network/pull/220) * Improving error messages [#232](https://github.com/haskell/network/pull/232) * Allow non-blocking file descriptors via `setNonBlockIfNeeded` [#242](https://github.com/haskell/network/pull/242) * Update config.{guess,sub} to latest version [#244](https://github.com/haskell/network/pull/244) * Rename `my_inet_ntoa` to avoid symbol conflicts [#228](https://github.com/haskell/network/pull/228) * Test infrastructure improvements [#219](https://github.com/haskell/network/pull/219) [#217](https://github.com/haskell/network/pull/217) [#218](https://github.com/haskell/network/pull/218) * House keeping and cleanup [#238](https://github.com/haskell/network/pull/238) [#237](https://github.com/haskell/network/pull/237) -------------- next part -------------- An HTML attachment was scrubbed... URL: From csasarak at mailbox.org Wed May 31 23:10:56 2017 From: csasarak at mailbox.org (Chris Sasarak) Date: Wed, 31 May 2017 19:10:56 -0400 Subject: [Haskell-cafe] is 'stack ghci' really experimental? In-Reply-To: References: Message-ID: <87bmq8tyf3.fsf@rainicorn.i-did-not-set--mail-host-address--so-tickle-me> It does allow you to navigate to errors, there is also stack support. The relevant page of the manual is here: https://haskell.github.io/haskell-mode/manual/latest/Interactive-Haskell.html#Interactive-Haskell -Chris Dennis Raddle writes: > Oh, I also wanted to ask about Haskell mode of Emacs and ghci. I have not > tried to run ghci from within Emacs, but I can imagine doing so would > provide an advantage. Does haskelll-mode parse line numbers in error > messages and jump to them? > > And is it possible to run 'stack ghci' from within haskell-mode? > > Thanks > D > > On Tue, May 30, 2017 at 7:39 PM, Dennis Raddle > wrote: > >> I noticed that the stack docs say 'stack ghci' is experimental. I assume >> it's a common need (certainly is for me) to interpret my code while >> developing. Is it safe to use 'stack ghci' or is there another way that is >> more robust? >> D >> > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From monkleyon at gmail.com Wed May 31 23:20:31 2017 From: monkleyon at gmail.com (MarLinn) Date: Thu, 1 Jun 2017 01:20:31 +0200 Subject: [Haskell-cafe] data mining, or something like it In-Reply-To: References: Message-ID: > Second, are there any Haskell libraries that can help with this task? In my own experience, Data Mining is a very interactive task. You want to keep your feedback loop as tight as possible. Therefore the user interface becomes an important part of your setup. Text-based interfaces just don't cut it. And now consider the state of GUIs in the Haskell world… Personally I like [Knime] for Data Mining. Funnily enough it's written in Java (based on Eclipse), but you can see how most of it would translate beautifully to a functional language. Lots of maps and folds in disguise. Yet more interesting is that the style of visual data-flow programming that's used in it also lends itself well to music generation. In other words what you need might not exist yet, but you may be a perfect candidate to improve the state of GUIs in Haskell. ;) Cheers, MarLinn [Knime](http://www.knime.org/knime-analytics-platform)