[Haskell-cafe] Unification of PolyTypeable TypeReps ?
Hi haskell-cafe In my current project I'm working with type representations created with PolyTypeable, and it turns out that given two type representations I need to find out if they are unifiable. I've looked at polytypeable-utils and see that they have some functions for substituting/applying/free vars, but it doesn't seem like a full solution for what I need. So my question is: is there a library to do this? is there a known way to transform the TypeRep's to make them more amenable to other unification libraries. I noticed that in GHC-api there is an unification library, and that there is also unification-fd. I wanted to ask here first in case someone can point me to the right direction. Thanks! -- Ismael ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Fundeps and overlapping instances
Hello, On Wed, Jul 7, 2010 at 2:14 PM, Simon Peyton-Jones simo...@microsoft.comwrote: We can’t permit overlap for type families because it is *unsound *to do so (ie you can break “well typed programs don’t go wrong”). But if it’s unsound for type families, it would not be surprising if it was unsound for fundeps too. (I don’t think anyone has done a soundness proof for fundeps + local constraints + overlapping instances, have they?) And indeed I think it is. It would be unsound only if the functional dependencies are not checked properly (which, as you say, is similar to the check for type families). Here is an example of a sound overlap: class C a b | a - b instance C String Char instance C [a] a Indeed, it would be OK to allow this sort of overlap for type families too, although there it would not be useful, because the more general case already provides the same information as the more specific one. In the case of overlapping instances, the more specific instance might provide a different implementation for the class methods, as usual. (disclaimer: I'm not a fan of overlapping instancesI think that some of the alternative proposals, such as the instance chains work, are nicer, but one would have to do same sort of checks there too). ** Imagine a system “FDL” that has functional dependencies and local type constraints. The big deal about this is that you get to exploit type equalities in **given** constraints. Consider Oleg’s example, cut down a bit: ** ** class C a b | a - b instance C Int Bool newtype N2 a = N2 (forall b. C a b = b) ** ** t2 :: N2 Int t2 = N2 True ** ** We end up type-checking (True :: forall b. C Int b = b). From the functional dependency we know that (b~Bool), so the function should typecheck. GHC rejects this program; FDL would not. ** ** But making use of these extra equalities in “given” constraints is quite tricky. To see why look first at Example 1: ** ** *module* X where class C a b | a - b ** ** data T a where MkT :: C a b = b - T a ** ** ** ** *module* M1 where import X instance C Int Char where ... f :: Char - T Int f c = MkT c ** ** *module* M2 where import X instance C Int Bool g :: T Int - Bool g (MkT x) = x ** ** *module* Bad where import M1 import M2 bad :: Char - Bool bad = g . f ** ** This program is unsound: it lets you cast an Int to a Bool; result is a seg-fault. You may say that the problem is the inconsistent functional dependencies in M1 and M2. But GHC won’t spot that. For type families, to avoid this we “*eagerly*” check for conflicts in type-family instances. In this case the conflict would be reported when compiling module Bad, because that is the first time when both instances are visible together. ** So any FDL system should also make this eager check for conflicts. I completely agree with this---we should never allow inconsistent instances to exist in the same scope. ** ** What about overlap? Here’s Example 2: ** ** {-# LANGUAGE IncoherentInstances #-} *module* Bad where import X -- Overlapping instances instance C Int Bool -- Instance 1 instance C a [a] -- Instance 2 ** ** f :: Char - T Int f c = MkT c -- Uses Instance 1 ** ** g :: T a - a g (MkT x) = x-- Uses Instance 2 ** ** bad :: Char - Int bad = g . f ** As in the above example, this program violates the functional dependency on class C and should be rejected, because the two instances are not consistent with each other. But at the moment GHC makes an exception for **existentials**. Consider Example 3: ** ** class C a b | a - b ** ** -- Overlapping instances instance C Int Bool -- Instance 1 instance C a [a] -- Instance 2 ** ** data T where MkT :: C a b = a - b - T ** ** f :: Bool - T f x = MkT (3::Int) x -- Uses Instance 1 ** ** g :: T - T g (MkT n x) = MkT n (reverse x) -- Uses Instance 2 ** ** bad :: Bool - T bad = g . f ** ** This program is malformed for the same reason as the previous one: the two instances violate the functional dependency on the class. ** ** But even nuking IncoherentInstances altogether is not enough. Consider this variant of Example 3, call it Example 4: *module* M where class C a b | a - b ** ** instance C a [a] -- Instance 2 ** ** data T where MkT :: C a b = a - b - T ** ** g :: T - T g (MkT n x) = MkT n (reverse x) -- Uses Instance 2 ** ** *module*
[Haskell-cafe] Troubles understanding Parsec Error Handling
I recently started writing my first application at work in Haskell and it deals with a lot of parsing. Among other things I often have to check for a lot of alternatives for fixed strings (parsing natural language text and people have a lot of ways to abbreviate the same thing in labels). So far I have been doing this basically via choice $ map (try . string) [ foo, bar, ... ] This works fine but has two disadvantages, it isn't very fast, in particular when many of the strings start with the same prefix and it also is a bit error prone since it breaks when you place a prefix of another string earlier in the list. My attempt at a solution was to use the bytestring-trie package for a little utility function that basically parses one character at a time, checks if the string parsed so far is in the trie and then calls itself recursively with the trie starting with that string. My attempt at that so far looks like this: (dependencies bytestring-trie, utf8-string and parsec 3) import qualified Data.ByteString.UTF8 as UTF8 import qualified Data.Trie as Trie import Text.Parsec import Text.Parsec.Text (GenParser) anyOf :: [String] - GenParser u String anyOf l = try $ anyOf' t where t = Trie.fromList $ zip (map UTF8.fromString l) (repeat ()) anyOf' :: Trie.Trie () - String - GenParser u String anyOf' t s = try $ do c - lookAhead $ anyChar let newS = s ++ [ c ] in case Trie.submap (UTF8.fromString newS) t of emptyT | Trie.null emptyT - case Trie.member (UTF8.fromString s) t of True - return s False - unexpected $ show newS++, expecting one of ++show l restT - do _ - anyChar try $ anyOf' restT newS A successful example usage would be: parseTest (do; r1 - anyOf [Hello, Hallo, Foo, HallofFame]; r2 - string bla; return (r1, r2)) Hallobla which results in (Hallo,bla) (the extra string parser is there so errors in parsing too much are not hidden). An error would result .e.g. from parseTest (do; r1 - anyOf [Hello, Hallo, Foo, HallofFame]; r2 - string bla; return (r1, r2)) Hallofbla which prints this: parse error at (line 1, column 8):unknown parse error And my question about this is made up of two parts 1. Why doesn't it print my unexpected message but instead says unknown parse error 2. Why is the location in the text off (I would expect it to fail at column 6 (first character beyond the result it could return) or 7 (first character that makes the string no prefix of any acceptable string) I am afraid my knowledge of Parsec internals is a bit too limited, some Google queries showed no similar problems and no obvious places in the Parsec source code to check for the answer to the first question in particular and I suspect the second is closely related to the first. Thanks for reading through my question and I hope someone knows the answer or at least some clues on where i might find it. Matthias Hoermann P.S.: I am hoping this time this works, last time it was rejected because google sends with @googlemail.com instead of @gmail.com for some reason. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Fundeps and overlapping instances
Hello, I disagree with your example. 1. Check that an instance is consistent with itself. For example, this should be rejected: instance C a b because it allows C Int Bool and C Int Char which violate the functional dependency. Functional dependencies are not used to pick types, they are used to pick instances. class C a b | a → b where k ∷ a f ∷ a → Maybe b The functional dependency allows you to have a method such as k that doesn't use all the arguments of the class. I expect to be able to make a instance that works for any b. instance C Int b where k = 2 f _ = Nothing Etienne Laurin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Troubles understanding Parsec Error Handling
Hi Matthias, On Wed, May 30, 2012 at 1:36 PM, Matthias Hörmann mhoerm...@gmail.comwrote: parseTest (do; r1 - anyOf [Hello, Hallo, Foo, HallofFame]; r2 - string bla; return (r1, r2)) Hallofbla which prints this: parse error at (line 1, column 8):unknown parse error And my question about this is made up of two parts 1. Why doesn't it print my unexpected message but instead says unknown parse error 2. Why is the location in the text off (I would expect it to fail at column 6 (first character beyond the result it could return) or 7 (first character that makes the string no prefix of any acceptable string) What version of parsec 3 are you using? In version 3.1.1, I get (using Text.Parsec.String instead of Text.Parsec.Text): parse error at (line 1, column 1): unexpected Hallofb, expecting one of [Hello,Hallo,Foo,HallofFame] which is what I would have expected, bearing in mind that 'try p' pretends that it hasn't consumed input when 'p' fails. I don't think you need to use 'try' in your 'anyOf' function, but you'll have to change it to handle seeing the end of input if the one-character look-ahead fails. Kevin -- Kevin Charter kevin.char...@acm.org ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Troubles understanding Parsec Error Handling
On Wed, May 30, 2012 at 3:11 PM, Kevin Charter kchar...@gmail.com wrote: What version of parsec 3 are you using? In version 3.1.1, I get (using Text.Parsec.String instead of Text.Parsec.Text): Ah, answered my own question. I gather you're using 3.1.2, since it's the first and so far only version with the Text.Parsec.Text module. Kevin -- Kevin Charter kevin.char...@acm.org ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Troubles understanding Parsec Error Handling
On Wed, May 30, 2012 at 4:18 PM, Kevin Charter kchar...@gmail.com wrote: On Wed, May 30, 2012 at 3:11 PM, Kevin Charter kchar...@gmail.com wrote: What version of parsec 3 are you using? In version 3.1.1, I get (using Text.Parsec.String instead of Text.Parsec.Text): Ah, answered my own question. I gather you're using 3.1.2, since it's the first and so far only version with the Text.Parsec.Text module. We changed how 'try' handled errors in some cases in between 3.1.1 and 3.1.2. I'll take a look at this. Antoine Kevin -- Kevin Charter kevin.char...@acm.org ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Troubles understanding Parsec Error Handling
* Matthias Hörmann mhoerm...@gmail.com [2012-05-30 21:36:13+0200] And my question about this is made up of two parts 1. Why doesn't it print my unexpected message but instead says unknown parse error 2. Why is the location in the text off (I would expect it to fail at column 6 (first character beyond the result it could return) or 7 (first character that makes the string no prefix of any acceptable string) Thanks for reporting. This is a regression introduced by me in this patch: Sun Feb 20 18:24:22 EET 2011 Roman Cheplyaka r...@ro-che.info * Choose the longest match when merging error messages The source of the regression is that parsec sometimes generates dummy (aka unknown) error messages when no actual error has occurred. In your case the dummy error has a bigger position because it was generated by anyChar inside lookAhead. So, when merging errors, before simply looking at the positions we should check if one of them is dummy and just ignore it. The patch is attached. With this patch your code prints: parse error at (line 1, column 7): unexpected Hallofb, expecting one of [Hello,Hallo,Foo,HallofFame] This is probably still somewhat confusing to a user of your code (there's no Hallofb starting at column 7), but is correct from Parsec's point of view, because you generated this message while looking at the 7th character. -- Roman I. Cheplyaka :: http://ro-che.info/ 1 patch for repository http://code.haskell.org/parsec3: Thu May 31 01:38:09 EEST 2012 Roman Cheplyaka r...@ro-che.info * When merging error messages, prefer known messages to unknown ones This fixes a regression introduced by: Sun Feb 20 18:24:22 EET 2011 Roman Cheplyaka r...@ro-che.info * Choose the longest match when merging error messages The source of the regression is that parsec sometimes generates dummy (aka unknown) error messages when no actual error has occurred. So, when merging errors, before simply looking at the positions we should check if one of them is unknown and just ignore it. Reported by Matthias Hörmann. New patches: [When merging error messages, prefer known messages to unknown ones Roman Cheplyaka r...@ro-che.info**20120530223809 Ignore-this: 1cfcc0a8d1cbfd183a3897e79c320c22 This fixes a regression introduced by: Sun Feb 20 18:24:22 EET 2011 Roman Cheplyaka r...@ro-che.info * Choose the longest match when merging error messages The source of the regression is that parsec sometimes generates dummy (aka unknown) error messages when no actual error has occurred. So, when merging errors, before simply looking at the positions we should check if one of them is unknown and just ignore it. Reported by Matthias Hörmann. ] { hunk ./Text/Parsec/Error.hs 137 = ParseError pos (msg : filter (msg /=) msgs) mergeError :: ParseError - ParseError - ParseError -mergeError (ParseError pos1 msgs1) (ParseError pos2 msgs2) +mergeError e1@(ParseError pos1 msgs1) e2@(ParseError pos2 msgs2) +-- prefer meaningful errors +| null msgs2 not (null msgs1) = e1 +| null msgs1 not (null msgs2) = e2 +| otherwise = case pos1 `compare` pos2 of -- select the longest match EQ - ParseError pos1 (msgs1 ++ msgs2) hunk ./Text/Parsec/Error.hs 145 -GT - ParseError pos1 msgs1 -LT - ParseError pos2 msgs2 +GT - e1 +LT - e2 instance Show ParseError where show err } Context: [TAG 3.1.2 Antoine Latter aslat...@gmail.com**20111008182138 Ignore-this: 96361fd74cad3d51b4213e0bcd91cdf3 ] [version bump for release Antoine Latter aslat...@gmail.com**20111008181844 Ignore-this: 9c28994644744eaf375d9c5d75d2b201 ] [add Stream Text instances Antoine Latter aslat...@gmail.com**20111008181718 Ignore-this: fcf1bc6a54bae9936669e28047c4f736 ] [Fix reserved name recognition for case-insensitive languages. Antoine Latter aslat...@gmail.com**20111008180454 Ignore-this: aed4027b1f273913f7586208e5a6f82c ] [Documentation fix Roman Cheplyaka r...@ro-che.info**20111228222953 Ignore-this: 2d226ed7cde7a8322be04f5188957eb2 ] [lookAhead: do not consume input on success; update documentation Roman Cheplyaka r...@ro-che.info**20110220162920 Ignore-this: e884771490209b93e9fec044543a18ef ] [try: do not reset the error position Roman Cheplyaka r...@ro-che.info**20110220162449 Ignore-this: 8508bc41fc6dcd9b7c06aac762f12c71 ] [Choose the longest match when merging error messages Roman Cheplyaka r...@ro-che.info**20110220162422 Ignore-this: 54e2733159a1574abb229e09ff6935c1 ] [TAG 3.1.1 Antoine Latter aslat...@gmail.com**20110129160030 Ignore-this: 42ddc9e7316d68945c2c1260c2acd403 ] Patch bundle hash: 09fc71cdc9e86dc672f19bc8fb939103cae782bb ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Troubles understanding Parsec Error Handling
Hi Antoine and Roman, On Wed, May 30, 2012 at 4:14 PM, Antoine Latter aslat...@gmail.com wrote: We changed how 'try' handled errors in some cases in between 3.1.1 and 3.1.2. I'll take a look at this. Antoine Thanks for confirming -- I tried 3.1.2 and got the same result as Matthias. And Roman, thanks for the light-speed patch! I was about to say I had an example that showed the problem might actually have to do with 'lookAhead' rather than 'try', and then I saw your message. Kevin -- Kevin Charter kevin.char...@acm.org ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Requesting Feedback: I Love Haskell, but can't find a place to use it
I love Haskell. It is my absolute favorite language. But I have a very hard time finding places where I can actually use it! I had hoped that compiling Haskell to C with -fvia-C (or would it be just -C?) would allow Haskell to run in new, uncharted territory such as Android (with NDK), IOS, Google's NaCl, etc. But today I learned that GHC's C backend has been deprecated! Is it more difficult than I am imagining to get Haskell to work in these environments? Is it simply a matter of low interest in this kind of work? Or something more fundamental? Am I missing something? I'm hoping that the Haskell-JavaScript efforts will mature enough to make Haskell viable for client-side web apps. (I think the first sign of this will be a self-hosting Haskell-JavaScript compiler.) I use Haskell for Server-Side code with various web frameworks, but over the years more and more of the app logic is moved into client-side JavaScript, leaving the server-side code as little more than a simple validation and security layer over the database and other services. Haskell doesn't have any trouble with this, of course, but it's not exactly a role where it can shine. (Of course this is not true of ALL server-side code, just the kind of apps I have been writing.) So anyway I'd like to request feedback: where can I use Haskell besides simple CLI utilities, dull server code, or project Euler problems? Even if it's just to contribute to getting Haskell in the environments mentioned above, any feedback is welcome! Thanks for reading, --J Arthur ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Haskell Weekly News: Issue 229
Welcome to issue 229 of the HWN, an issue covering crowd-sourced bits of information about Haskell from around the web. This issue covers the week of May 20 to 26, 2012. Quotes of the Week * Peaker: Harrop taught me that I am a team of experts * applicative: Even if no one else understands me, still, the Glasgow Haskell Compiler understands me * JoeyA: Answers in #haskell are automatically sorted by readability descending. * monochrom: monochromism is a graph morphism that maps graphs to 1-colorable graphs :) * sipa: can we write a TutorialMonad t ? which is used to build and combine monad tutorials? Top Reddit Stories * my Haskell project was 100% funded on Kickstarter Domain: self.haskell, Score: 125, Comments: 22 On Reddit: [1] http://goo.gl/E2wkY Original: [2] http://goo.gl/E2wkY * Building intuition for monads, without mentioning monads (Ertugrul Söylemez) Domain: haskell.org, Score: 56, Comments: 32 On Reddit: [3] http://goo.gl/2leRd Original: [4] http://goo.gl/kMbJR * A gamified tutorial on the sequent calculus Domain: logitext.ezyang.scripts.mit.edu, Score: 51, Comments: 23 On Reddit: [5] http://goo.gl/tD8fZ Original: [6] http://goo.gl/E6zBl * pipes 2.0 - Pipe Finalization Domain: haskellforall.com, Score: 45, Comments: 32 On Reddit: [7] http://goo.gl/boq03 Original: [8] http://goo.gl/AABwV * Haste: Haskell to Javascript Compiler Domain: github.com, Score: 40, Comments: 45 On Reddit: [9] http://goo.gl/sJCcJ Original: [10] http://goo.gl/ZhYbP * Monad Reification in Haskell and the Sunroof Javascript compiler Domain: ittc.ku.edu, Score: 37, Comments: 26 On Reddit: [11] http://goo.gl/LVSVO Original: [12] http://goo.gl/s0PVp * HaskSymb, An Experiment in Haskell Symbolic Algebra. Feedback appreciated! Domain: github.com, Score: 36, Comments: 34 On Reddit: [13] http://goo.gl/d6Xo8 Original: [14] http://goo.gl/TUiJt * Using Ragel, Clang, LLVM and GHC to produce really fast stockmarket data parsers Domain: breaks.for.alienz.org, Score: 35, Comments: 8 On Reddit: [15] http://goo.gl/qEmKb Original: [16] http://goo.gl/ABzsA * Looks like Bryan finished importing Cabal issues to Github — thanks! Domain: github.com, Score: 32, Comments: 6 On Reddit: [17] http://goo.gl/9O8Sa Original: [18] http://goo.gl/bWrLg * What if haskellwiki were run by a Haskell wiki? Domain: haskellwiki.gitit.net, Score: 29, Comments: 14 On Reddit: [19] http://goo.gl/713Yb Original: [20] http://goo.gl/chSPM * New release of Elm available. Looking for feedback on the language so far. Domain: self.haskell, Score: 24, Comments: 21 On Reddit: [21] http://goo.gl/ejS9p Original: [22] http://goo.gl/ejS9p * Generics and Protocol Buffers Domain: breaks.for.alienz.org, Score: 17, Comments: On Reddit: [23] http://goo.gl/z0obj Original: [24] http://goo.gl/R5b3l Top StackOverflow Questions * What's the theoretical basis for existential types? votes: 32, answers: 3 Read on SO: [25] http://goo.gl/ZdAJb * How can a gc find out about object references done from the stack? votes: 20, answers: 4 Read on SO: [26] http://goo.gl/AtXUr * Why is GHC complaining about non-exhaustive patterns? votes: 14, answers: 3 Read on SO: [27] http://goo.gl/9oIsB * Evolving data structure votes: 13, answers: 2 Read on SO: [28] http://goo.gl/gbeLN * What makes a good name for a helper function? votes: 11, answers: 5 Read on SO: [29] http://goo.gl/b6B7o * Haskell “Apply”? [closed] votes: 11, answers: 3 Read on SO: [30] http://goo.gl/EBwsy * Round to nearest integer votes: 10, answers: 1 Read on SO: [31] http://goo.gl/1RaVk * Haskell: lazy versus eager evaluation for insertion sort votes: 6, answers: 1 Read on SO: [32] http://goo.gl/zGrie * Loss of polymorphism after pattern matching votes: 6, answers: 1 Read on SO: [33] http://goo.gl/YmA1y * Church-Rosser Theorem Example in a Functional Programming Language votes: 6, answers: 1 Read on SO: [34] http://goo.gl/FmSMh Until next time, Daniel Santa Cruz References 1. http://www.reddit.com/r/haskell/comments/u2vt5/my_haskell_project_was_100_funded_on_kickstarter/ 2. http://www.reddit.com/r/haskell/comments/u2vt5/my_haskell_project_was_100_funded_on_kickstarter/ 3. http://www.haskell.org/pipermail/haskell-cafe/2012-May/101338.html 4. http://www.reddit.com/r/haskell/comments/u04vp/building_intuition_for_monads_without_mentioning/ 5. http://logitext.ezyang.scripts.mit.edu/logitext.fcgi/tutorial 6. http://www.reddit.com/r/haskell/comments/tzp7f/a_gamified_tutorial_on_the_sequent_calculus/ 7. http://www.haskellforall.com/2012/05/pipes-20-pipe-finalization.html
Re: [Haskell-cafe] Requesting Feedback: I Love Haskell, but can't find a place to use it
On Wed, May 30, 2012 at 8:30 PM, Jonathan Geddes geddes.jonat...@gmail.comwrote: I had hoped that compiling Haskell to C with -fvia-C (or would it be just -C?) would allow Haskell to run in new, uncharted territory such as Android (with NDK), IOS, Google's NaCl, etc. But today I learned that GHC's C backend has been deprecated! Is it more difficult than I am imagining to get Haskell to work in these environments? Is it simply a matter of low interest in this kind of work? Or something more fundamental? Am I missing something? The C backend was never suitable for that; it couldn't cross-compile and it used some crufty Perl to apply dubious optimizations to the generated code (and never did anything interesting on x86 anyway due to lack of registers). The portable ANSI C backend, which is used to port GHC to a new platform in the absence of cross-compilation, still works — but produces rather slow code. The native and LLVM backends are much better, and there is at least some potential for cross-compilation. I believe there is work proceeding on an ARM native code generator that can be used to target Android. -- brandon s allbery allber...@gmail.com wandering unix systems administrator (available) (412) 475-9364 vm/sms ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Finding the average in constant space
Sorry for the delayed response -- I've had exams the past few days. On Sun, May 27, 2012 at 8:21 PM, Eugene Kirpichov ekirpic...@gmail.com wrote: A lot of people have done this :) eg from me: google up a fairly recent thread from me about processing streams and perhaps the keyword timeplot (writing from a dying phone, can't do myself) If you mean this: http://www.haskell.org/pipermail/haskell-cafe/2011-December/097908.html and this: https://github.com/jkff/timeplot/blob/master/Tools/TimePlot/Incremental.hs then you're right -- the types match up exactly! The funny thing is, I remember seeing that message half a year ago and having absolutely no idea what any of it meant. Now I've actually tried it myself, reifying the case expression actually makes perfect sense. On Sun, May 27, 2012 at 11:43 PM, Stephen Tetley stephen.tet...@gmail.com wrote: There are a few blog posts by Conal Elliott and Max Rabkin (I think) reifying folds as a data type to get more composition and thus fold different functions at the same time. Search for beautiful folding with the above authors names. Personally I didn't find the examples significantly more beautiful that using regular composition in a normal fold - only that that the helper functions to manage pairs aren't in the standard library. This was already bookmarked, funnily enough: http://squing.blogspot.co.nz/2008/11/beautiful-folding.html I don't think that solution was particularly beautiful either. It seems a bit over-the-top, hiding the state in an existential type when a simple closure would do. However, I don't understand what you mean by regular composition in a normal fold. Wait, what's an irregular composition? Abnormal fold? ;) On Mon, May 28, 2012 at 7:33 AM, Steffen Schuldenzucker sschuldenzuc...@uni-bonn.de wrote: This is (a special case of) the main point in the design of iteratees. See e.g. the definition of the 'Iteratee' type in the enumeratee library. - Looks pretty much like your 'Fold' type with an additional state (done or not yet done). Also, the pipe package seems to provide something similar. I haven't looked too much into iteratees until now, but in hindsight it seems obvious why they're implemented that way -- they have to iterate over a stream chunk by chunk, keeping state as they go along, just like the Fold type. Thanks for pointing that out! Chris ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Fundeps and overlapping instances
Hello, the notion of a functional dependency is well established, and it was used well before it was introduced to Haskell (for example, take a look at http://en.wikipedia.org/wiki/Functional_dependency). So I'd be weary to redefine it lightly. Note that placing a functional dependency constraint is just one way to allow class methods that don't mention all class variables. If the instances for the class do not satisfy the functional dependency (as in your example), you can refactor your class hierarchy, instead. For example: class D a where k :: a class D a = C a b where f :: a - b instance D Int where k = 2 instance C Int b where f _ = Nothing I hope this helps, -Iavor On Wed, May 30, 2012 at 1:31 PM, Etienne Laurin etie...@atnnn.com wrote: Hello, I disagree with your example. 1. Check that an instance is consistent with itself. For example, this should be rejected: instance C a b because it allows C Int Bool and C Int Char which violate the functional dependency. Functional dependencies are not used to pick types, they are used to pick instances. class C a b | a → b where k ∷ a f ∷ a → Maybe b The functional dependency allows you to have a method such as k that doesn't use all the arguments of the class. I expect to be able to make a instance that works for any b. instance C Int b where k = 2 f _ = Nothing Etienne Laurin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to write Source for TChan working with LC.take?
Thanks! I just read your article. I think your proposal is rational, useful and so brilliant! The new yield/await style would make writing conduits much easier. Thank you again for taking so much time for this problem! On 2012/05/29, at 22:14, Michael Snoyman wrote: OK, after thinking on this for the past week, I've come up with a proposal to make this kind of code easier to write (and more of an explanation on why the behavior was unintuitive in the first place). http://www.yesodweb.com/blog/2012/05/next-conduit-changes Do you think the modified yield/await would be a good solution to the problem? Michael On Mon, May 21, 2012 at 6:07 AM, Michael Snoyman mich...@snoyman.com wrote: I agree that this behavior is non-intuitive, but still believe it's the necessary approach. The short answer to why it's happening is that there's no exit path in the yield version of the function. To understand why, let's expand the code a little bit. Realizing that liftIO = lift . liftIO and lift mr = PipeM (Done Nothing `liftM` mr) (Finalize mr) we can expand the yield version into: sourceTChanYield2 ch = forever $ do let action = liftIO . atomically $ readTChan ch ans - PipeM (Done Nothing `liftM` action) (FinalizeM action) yield ans So the first hint that something is wrong is that the finalize function is calling the action. If you try to change that finalize action into a no-op, e.g.: sourceTChanYield3 :: MonadIO m = TChan a - Source m a sourceTChanYield3 ch = forever $ do let action = liftIO . atomically $ readTChan ch ans - PipeM (Done Nothing `liftM` action) (return ()) yield ans then you get an error message: test.hs:36:53: Could not deduce (a ~ ()) The problem is that, as the monadic binding is set up here, the code says after running the PipeM, I want you to continue by yielding, and then start over again. If you want to expand it further, you can change `forever` into a recursive call, expand `yield`, and then expand all the monadic binding. Every finalization call is forcing things to keep running. And remember: all of this is the desired behavior of conduit, since we want to guarantee finalizers are always called. Imagine that, instead of reading data from a TChan, you were reading from a Handle. In the code above, there was no way to call out to the finalizers. Not sure if all of that rambling was coherent, but here's my recommended solution. What we need is a helper function that allows you to branch based on whether or not it's time to clean up. `lift`, `liftIO`, and monadic bind all perform the same actions regardless of whether or not finalization is being called. The following code, however, works correctly: liftFinal :: Monad m = m a - Finalize m () - (a - Source m a) - Source m a liftFinal action final f = PipeM (liftM f action) final sourceTChanYield :: Show a = MonadIO m = TChan a - Source m a sourceTChanYield ch = liftFinal (liftIO . atomically $ readTChan ch) (return ()) $ \ans - do yield ans sourceTChanYield ch Michael On Sun, May 20, 2012 at 4:22 PM, Hiromi ISHII konn.ji...@gmail.com wrote: Oops, sorry. The last case's behaviour was not as I expected... A correct log is below: ghci sourceTChanRaw ch $$ LC.isolate 10 =$= LC.mapM_ print () () () () () () () () () () ghci sourceTChanState ch $$ LC.isolate 10 =$= LC.mapM_ print () () () () () () () () () () ghci sourceTChanYield ch $$ LC.isolate 10 =$= LC.mapM_ print () () () () () () () () () () *blocks* So again, sourceTChanYield blocks here even if it is already supplied with enough values! -- Hiromi ISHII konn.ji...@gmail.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -- Hiromi ISHII konn.ji...@gmail.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe