From carter.schonwald at gmail.com Sat Jan 2 21:59:11 2021 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Sat, 2 Jan 2021 16:59:11 -0500 Subject: [Haskell-cafe] [ANN] fp-ieee v0.1 In-Reply-To: References: <44F911D8-A142-412A-8A84-E78BB06A4812@gmail.com> Message-ID: huh, do you mean you're using round ties to odd (if so please elaborate! i feel like there must be an interesting insight or observation) OR that youve a software implementation of roundties to odd? I feel like i'm missing happy new year! -Carter On Thu, Dec 31, 2020 at 4:08 AM ARATA Mizuki wrote: > > > > 2020/12/29 0:14、Carter Schonwald のメール: > > > > This is really cool! > > Thanks. > > > > > Is the fall back strategy to do Kahn style compensated arithmetic. > Similar to in Edward Kmett’s compensated library on hackage? > > Yes. My code combines it with "round-to-odd" technique. > > > > > I like how you have both styles of NaN semantics for min and max, with > the default being NaN poisoning but also providing the NaN avoiding one > some software needs to do. > > It's one of the new things in IEEE 754-"2019" :) > > > > > On Mon, Dec 28, 2020 at 7:06 AM ARATA Mizuki > wrote: > > Hi all, > > > > I'd like to announce the first release of fp-ieee. > > > > https://hackage.haskell.org/package/fp-ieee > > > > This library aims to provide IEEE 754-2019 compliant operations, > including > > > > * fusedMultiplyAdd > > > > * correctly-rounding versions of fromInteger (GHC's fromInteger for > Float and Double do not round correctly; see > https://gitlab.haskell.org/ghc/ghc/-/issues/17231) > > > > * realFloatToFrac: an alternative of realToFrac with well-defined > semantics. > > > > Other notes: > > > > * Most of the functions are generic, and any RealFloat instance can be > used. However, manipulation of NaN's sign and payload requires an > additional constraint (RealFloatNaN, provided by this library). > > > > * Access to floating-point environment is not provided. If you want to > control rounding direction, look at my another library: > https://hackage.haskell.org/package/rounded-hw > > > > * Decimal-specific operations (like quantize, quantum) are not provided, > and the preferred exponent is not honored. > > > > * Use of FFI can be disabled via a package flag (maybe useful when using > non-native targets). > > > > > > Mizuki > > > > _______________________________________________ > > 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 safinaskar at mail.ru Sat Jan 2 23:59:20 2021 From: safinaskar at mail.ru (=?UTF-8?B?QXNrYXIgU2FmaW4=?=) Date: Sun, 03 Jan 2021 02:59:20 +0300 Subject: [Haskell-cafe] =?utf-8?q?How_to_do_reversible_parsing=3F?= Message-ID: <1609631960.590531545@f720.i.mail.ru> Hi. How to do deterministic reversible parsing in Haskell? Please, point me to some libs or tools. Or give some advice on how to write such lib or tool. (Also, I am interested in solutions for C or C++.) Now let me explain my task in detail. I am interested in formal math. I am going to develop various proof checkers. In particular, I want to develop my PTS checker ( https://en.wikipedia.org/wiki/Pure_type_system ). Here is example of existing PTS checker: http://web.archive.org/web/20180924133846/http://www.cs.kun.nl/~janz/yarrow/ . Here is example of input this checker accepts (taken from manual): Var (+) : Nat -> Nat -> Nat Def double := \x:Nat. x+x Def S := (+) one Also, I want to develop something similar to Isabelle ( https://isabelle.in.tum.de/ ). Example of Isabelle input: https://isabelle.in.tum.de/dist/library/HOL/HOL/HOL.html . Also, I am going to write converters between various languages. For example, between input for some existing PTS checker and my PTS checker. In short, I want to write lot of parsers and pretty-printers for various languages. And thus I need some parsing solution. The solution should have the following features: 1. The parsing should be divided into lexing and parsing. I. e. usual lex + yacc model. Parsing should be done using usual context-free grammars (CFGs). Left-recursive grammars should be supported (this leaves out parser combinator libraries). All languages I am going to deal with fit this model. I. e. I will deal with simple to parse languages, such as Pascal. Not complex ones, like C or C++. 2. Parsing should be deterministic. I. e. parser should check that CFG is unambiguous. Yes, I know that this task is impossible to do on Turing machine. But at very least some partial solution will go. For example, some algorithm, which will check that some reasonable set of CFGs is deterministic. Or even brute force up to some limit will go. (Yes, this will not give absolutely correct results, but this will go.) This is example of grammar for PTS in one of my checkers (start symbol is t0): t1000 = id t1000 = "(" t0")" t999 = t999 t1000 t3 = t4 "::" t3 t3 = "%" id "::" t0 "." t3 t0 = "!!" id "::" t0 "." t0 t1 = t2 "==>" t1 t0 = t1 t1 = t2 t2 = t3 t3 = t4 t4 = t999 t999 = t1000 If I remember correctly, this grammar is deterministic (checked using brute force up to a limit). I want solution which will verify that this grammar is deterministic. All stages of parsing should be proved as deterministic (i. e. scanner too). 3. Parsing should be reversible. I. e. pretty-printing should be supported, too. And the tool should guarantee that parsing and pretty-printing match. Now let me give more precise definition. Let's assume we have these functions: parse :: String -> Maybe X print :: X -> Maybe String As you can see, not every internal representation is printable. This is OK. For example, if internal representation contains variable names that happen to equal reserved words, then, of course, this is unprintable representation. The tool should guarantee that: a. Result of parsing should be printable, but printing not necessary should give same string. I. e. if "parse s == Just x", then "print x /= Nothing". (But not necessary "print x == Just s".) b. Parsing of result of printing should give same representation. I. e. if "print x == Just s", then "parse s == Just x" 4. Not only parsing should generate parse tree (i. e. exact representation of derivation), but also AST. AST differs from parse tree. For example, AST should not contain braces. I. e. "2 + (3 * 4)" and "2 + 3 * 4" should give same AST. And the tool should be able parse string to AST and pretty print AST back to string. 5. It should be possible to use CFG not known in compile time. Consider Isabelle language. Here is again example of Isabelle text: https://isabelle.in.tum.de/dist/library/HOL/HOL/HOL.html . As you can see the language is divided into inner language and outer language. Strings in inner language are quoted. Outer language can add productions to inner language. Inner language cannot change itself. "notation" and "translations" commands add productions to inner language. So inner language is not known beforehand, it is created dynamically. There is no need to dynamically create scanner, i. e. it should be possible to dynamically create parser (for inner language), but there is no such requirement for scanner. Also, parser will not change in the middle of parsing given string. Again: let's assume I write parser for my Isabelle analog. Scanner and parser for outer language is fixed. Scanner for inner language is fixed, too. But parser for inner language is not. I read input document and add productions to CFG of inner language on the fly. Every time I add production, resulting CFG should be checked for ambiguity. And when I find inner language string in input, I process it using just constructed parser for inner language. -- Points 2 and 3 are the most important in this list. If there is solution which contains them alone, this already will be very good. Now let me list considered solutions. * Usual combinator libraries (such as parsec) will not go. They don't work with left-recursive CFGs. They don't check grammars for ambiguities. They don't do reversible parsing. But they allow creating language on the fly, and this is good thing. * Happy and alex will not go. As well as I know Happy can prove unambiguity of some very simple grammars (i. e. for some set of simple grammars it will not report any conflicts and thus will prove they unambiguity). It seems this is LR(1) set. But, as well as I know, Happy will report conflicts on PTS grammar given above, i. e. Happy cannot prove its unambiguity. Also, Happy and Alex cannot pretty-print. And Happy and Alex don't allow supplying CFG on the fly. * Package "earley". Handle arbitrary CFGs, including left-recursive. This is good thing. It seems CFG can be supplied in runtime. This is good thing, too. Gives all parse trees, thus we can verify that count of parse trees equals to 1. This is good thing, too. Unfortunately, earley cannot verify CFS's unambiguity before supplying input. Also, earley doesn't support pretty-printing. * PEG libraries. Will not go, I want CFGs. * I searched on Hackage reversible parsing libraries. Unfortunately, none of them guarantee reversibility. I. e. it is very easy to fool these libraries and create parsers and printers not satisfying equations I gave above. Also, this libraries doesn't have other features I mentioned * http://augeas.net/ is very cool project. Unlike nearly everything I found in internet, Augeas provides guaranteed reversible parsing and pretty-printing (!!!!!). Unfortunately, set of supported target languages is very limited. Regular languages are supported. And some very limited set of CFGs is supported. For example, it is possible to construct parser for JSON. But parser for Pascal seems impossible. Augeas not designed for parsing programming languages. Only simple configuration languages like JSON, XML, etc. Mutually recursive nonterminals are not supported. Also, Augeas provides C API, not Haskell one. * https://www.brics.dk/xsugar.html is very good. It provides guaranteed reversible translation between arbitrary language and XML. And XSugar even verifies unambiguity of the CFG using some sophisticated algorithm. Unfortunately, this algorithm still cannot prove unambiguity of PTS grammar given above. Also, XSugar is not Haskell library. It is standalone Java app. So, I need to convert some language to XML, then load this XML to my Haskell program and parse. Also, there is similar lib https://www.brics.dk/Xact.html from same author, but it is for Java, not for Haskell. I was able to find only 2 projects, which do guaranteed reversible parsing: mentioned Augeas and XSugar/Xact. Unfortunately, both are not for Haskell. And both cannot prove unambiguity for my PTS grammar. So, please tell me about solution. Or give advice how to write one. Also, let me describe my experience with various algorithms for checking ambiguity of grammar. 1. Try to construct LR(1) table. If there is no conflicts, then the grammar is unambiguous. It seems this is algorithm used by bison and happy. Unfortunately it is too weak and cannot prove unambiguity of my PTS grammar. 2. Try to construct LR(k) table. This algorithm is stronger than LR(1). I was unable to find implementation of this algorithm in any language. I don't want to write such algorithm. 3. Schmitz's algorithm. http://www.lsv.fr/~schmitz/pub/expamb.pdf . Even stronger than LR(k). I downloaded his bison fork. Unfortunately this bison fork can prove unambiguity for same set of grammars original bison can (i. e. LR(1)). I. e. it seems Schmitz did not implemented his algorithm. I don't want to implement his algorithm either. 4. Horizontal and vertical ambiguity checking. https://www.brics.dk/grammar/kruse.pdf . This is algorithm used in XSugar. Unfortunately, it doesn't handle my PTS grammar. 5. Brute force up to some limit. Doesn't give unambiguity guarantee. But I like it, and I will use it if I don't find anything else. It is the only algorithm which can handle my PTS grammar (and give enough amount of guarantee), not counting LR(k) and Schmitz's algorithm (I was not able to find implementations of both). I will try to write tool I want, I will write about my progress to this list. == Askar Safin https://github.com/safinaskar From johannes.waldmann at htwk-leipzig.de Sun Jan 3 01:58:12 2021 From: johannes.waldmann at htwk-leipzig.de (Johannes Waldmann) Date: Sun, 3 Jan 2021 02:58:12 +0100 Subject: [Haskell-cafe] How to do reversible parsing? Message-ID: <2933bd03-6c59-495a-d464-149fff943dc0@htwk-leipzig.de> Rendell and Ostermann, Invertible syntax descriptions, Haskell Symposium '10 https://doi.org/10.1145/1863523.1863525 https://hackage.haskell.org/package/invertible-syntax For the general background, see, e.g., Grohne and Voigtländer 2017 Formalizing semantic bidirectionalization ... https://doi.org/10.1016/j.jlamp.2016.04.002 And there's a workshop series on Bidirectional Transformations (from 2012 onwards) - J. From mgajda at mimuw.edu.pl Sun Jan 3 13:15:38 2021 From: mgajda at mimuw.edu.pl (Michal J Gajda) Date: Sun, 3 Jan 2021 14:15:38 +0100 Subject: [Haskell-cafe] How to do reversible parsing? In-Reply-To: References: Message-ID: Hi Askar, > Hi. How to do deterministic reversible parsing in Haskell? Please, point me to some libs or tools. > Or give some advice on how to write such lib or tool. (Also, I am interested in solutions for C or C++.) > > Now let me explain my task in detail. I liked the bidirectional applicatives and monads described in here: 1. Composing bidirectional programs monadically (with appendices) - Li-yao Xia, Dominic Orchard, Meng Wang https://arxiv.org/abs/1902.06950 You can use it for both bidirectional parsing/pretty pretting and type inference/type checking. 2. BiGuL is a bit more complicated: https://bitbucket.org/prl_tokyo/bigul/src/master/ -- Cheers Michał From johannes.waldmann at htwk-leipzig.de Sun Jan 3 14:15:19 2021 From: johannes.waldmann at htwk-leipzig.de (Johannes Waldmann) Date: Sun, 3 Jan 2021 15:15:19 +0100 Subject: [Haskell-cafe] How to do reversible parsing? In-Reply-To: <2933bd03-6c59-495a-d464-149fff943dc0@htwk-leipzig.de> References: <2933bd03-6c59-495a-d464-149fff943dc0@htwk-leipzig.de> Message-ID: <7b44d537-123d-cd6c-0893-e9049ec005d0@htwk-leipzig.de> Perhaps you don't even need to pretty-print? If you're just echoing parts of the input, then have the parser add source range annotations to the AST. (Example: see Section A.2 of https://arxiv.org/abs/2009.01326) Of course, if you are generating code, then this does not work. - J. From P.Achten at cs.ru.nl Mon Jan 4 15:27:39 2021 From: P.Achten at cs.ru.nl (Peter Achten) Date: Mon, 4 Jan 2021 16:27:39 +0100 Subject: [Haskell-cafe] [TFPIE'21] Third and Final Call For Papers: Trends in Functional Programming *in Education* 2021, 16 February 2021 (with Lambda Days 2021 & TFP 2021) Message-ID: <3303da47-848b-92c1-f265-41e69d9d8bd9@cs.ru.nl> ----------------------------------------------    TFPIE 2021 3rd and Final Call for papers ---------------------------------------------- *************************************************************** -  Submission deadline: January 11 2021, Anywhere on Earth. *************************************************************** https://wiki.tfpie.science.ru.nl/TFPIE2021#TFPIE_2021 (February 16 2021, co-organized with TFP 2021 and Lambda Days 2021) Because of the covid pandemic, the events are online this year. The goal of the International Workshops on Trends in Functional Programming in Education is to gather researchers, professors, teachers, and all 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. TFPIE 2021 welcomes submissions in the above mentioned areas. This year many teaching programmes have had to make a rapid transition to online teaching, and we explicitly solicit papers that explore this area of teaching functional programming. 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. The length of the presentation should be comparable to that of a paper. On top of the lecture itself, the presentation can also provide commentary on the lecture. Submissions Potential presenters are invited to submit an extended abstract (4-6 pages) or a draft paper (up to 20 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=tfpie2021 After the workshop, presenters are invited to submit (a revised version of) their article for review. The PC will select the best articles for publication in the Electronic Proceedings in Theoretical Computer Science (EPTCS). Articles rejected for presentation and extended abstracts will not be formally reviewed by the PC. Dates -  Submission deadline: January 11 2021, Anywhere on Earth. -  Notification: January 15 2021 -  Workshop: February 16 2021 -  Submission for formal review: April 20 2021, Anywhere on Earth. -  Notification of full article: June 7 2021 -  Camera ready: July 1st 2021 Program Committee - Peter Achten,    Radboud University, Netherlands (chair) - Edwin Brady,     University of St Andrews, UK - Laura Castro,    Universidade da Coruña, Spain - Stephen Chang,   University of Massachusetts Boston, USA - Youyou Cong,     Tokyo Institute of Technology, Japan - Matthew Flatt,   University of Utah, USA - Seth Fogarty,    Trinity University, USA - Alex Gerdes,     University of Gothenburg, Sweden - Gabriele Keller, Utrecht University, Netherlands - Prabhakar Ragde, University of Waterloo, Canada - Melinda Tóth,    Eötvös Loránd University, Budapest, Hungary Registration TFPIE is part of Lambda Days. Please visit the Lambda Days 2021 pages when registration information becomes available. Only papers that have been presented at TFPIE may be submitted to the post-reviewing process. Information on Lambda Days is available at https://www.lambdadays.org/lambdadays2021 Information on TFP         is available at http://tfp2021.org From blamario at rogers.com Mon Jan 4 18:23:30 2021 From: blamario at rogers.com (Mario) Date: Mon, 4 Jan 2021 13:23:30 -0500 Subject: [Haskell-cafe] How to do reversible parsing? In-Reply-To: <1609631960.590531545@f720.i.mail.ru> References: <1609631960.590531545@f720.i.mail.ru> Message-ID: <5c12b611-a469-a23d-94c6-0206caed6bd5@rogers.com> That's one ambitious research program you've taken on. I'm not aware of any complete solution, nor even anything close to it. I can only provide a couple of potentially useful pieces. I'm the author of the grammatical-parsers and construct Haskell libraries. The former can handle left-recursive grammars, the latter is bidirectional. I hope you can find some inspiration there. [1] http://hackage.haskell.org/package/grammatical-parsers [2] http://hackage.haskell.org/package/construct On 2021-01-02 6:59 p.m., Askar Safin via Haskell-Cafe wrote: > Hi. How to do deterministic reversible parsing in Haskell? Please, point me to some libs or tools. > Or give some advice on how to write such lib or tool. (Also, I am interested in solutions for C or C++.) > > Now let me explain my task in detail. > > I am interested in formal math. I am going to develop various proof checkers. In particular, I want > to develop my PTS checker ( https://en.wikipedia.org/wiki/Pure_type_system ). Here is example of > existing PTS checker: http://web.archive.org/web/20180924133846/http://www.cs.kun.nl/~janz/yarrow/ . > Here is example of input this checker accepts (taken from manual): > > Var (+) : Nat -> Nat -> Nat > Def double := \x:Nat. x+x > Def S := (+) one > > Also, I want to develop something similar to Isabelle ( https://isabelle.in.tum.de/ ). Example of > Isabelle input: https://isabelle.in.tum.de/dist/library/HOL/HOL/HOL.html . > > Also, I am going to write converters between various languages. For example, between input for some > existing PTS checker and my PTS checker. > > In short, I want to write lot of parsers and pretty-printers for various languages. And thus I need > some parsing solution. > > The solution should have the following features: > > 1. The parsing should be divided into lexing and parsing. I. e. usual lex + yacc model. Parsing should > be done using usual context-free grammars (CFGs). Left-recursive grammars should be supported (this > leaves out parser combinator libraries). All languages I am going to deal with fit this model. I. e. > I will deal with simple to parse languages, such as Pascal. Not complex ones, like C or C++. > > 2. Parsing should be deterministic. I. e. parser should check that CFG is unambiguous. Yes, I know > that this task is impossible to do on Turing machine. But at very least some partial solution will > go. For example, some algorithm, which will check that some reasonable set of CFGs is deterministic. > Or even brute force up to some limit will go. (Yes, this will not give absolutely correct results, > but this will go.) This is example of grammar for PTS in one of my checkers (start symbol is t0): > > t1000 = id > t1000 = "(" t0")" > t999 = t999 t1000 > t3 = t4 "::" t3 > t3 = "%" id "::" t0 "." t3 > t0 = "!!" id "::" t0 "." t0 > t1 = t2 "==>" t1 > t0 = t1 > t1 = t2 > t2 = t3 > t3 = t4 > t4 = t999 > t999 = t1000 > > If I remember correctly, this grammar is deterministic (checked using brute force up to a limit). > I want solution which will verify that this grammar is deterministic. > > All stages of parsing should be proved as deterministic (i. e. scanner too). > > 3. Parsing should be reversible. I. e. pretty-printing should be supported, too. And the tool should > guarantee that parsing and pretty-printing match. Now let me give more precise definition. Let's > assume we have these functions: > > parse :: String -> Maybe X > print :: X -> Maybe String > > As you can see, not every internal representation is printable. This is OK. For example, if internal > representation contains variable names that happen to equal reserved words, then, of course, this is > unprintable representation. > > The tool should guarantee that: > a. Result of parsing should be printable, but printing not necessary should give same string. I. e. > if "parse s == Just x", then "print x /= Nothing". (But not necessary "print x == Just s".) > b. Parsing of result of printing should give same representation. I. e. if "print x == Just s", then > "parse s == Just x" > > 4. Not only parsing should generate parse tree (i. e. exact representation of derivation), but also > AST. AST differs from parse tree. For example, AST should not contain braces. I. e. "2 + (3 * 4)" and > "2 + 3 * 4" should give same AST. And the tool should be able parse string to AST and pretty print > AST back to string. > > 5. It should be possible to use CFG not known in compile time. Consider Isabelle language. Here is > again example of Isabelle text: https://isabelle.in.tum.de/dist/library/HOL/HOL/HOL.html . As you can > see the language is divided into inner language and outer language. Strings in inner language are > quoted. Outer language can add productions to inner language. Inner language cannot change itself. > "notation" and "translations" commands add productions to inner language. So inner language is not > known beforehand, it is created dynamically. There is no need to dynamically create scanner, i. e. > it should be possible to dynamically create parser (for inner language), but there is no such > requirement for scanner. Also, parser will not change in the middle of parsing given string. > > Again: let's assume I write parser for my Isabelle analog. Scanner and parser for outer language is > fixed. Scanner for inner language is fixed, too. But parser for inner language is not. I read input > document and add productions to CFG of inner language on the fly. Every time I add production, > resulting CFG should be checked for ambiguity. And when I find inner language string in input, I > process it using just constructed parser for inner language. > > -- > > Points 2 and 3 are the most important in this list. If there is solution which contains them alone, > this already will be very good. > > Now let me list considered solutions. > > * Usual combinator libraries (such as parsec) will not go. They don't work with left-recursive CFGs. > They don't check grammars for ambiguities. They don't do reversible parsing. But they allow creating > language on the fly, and this is good thing. > > * Happy and alex will not go. As well as I know Happy can prove unambiguity of some very simple grammars > (i. e. for some set of simple grammars it will not report any conflicts and thus will prove they unambiguity). > It seems this is LR(1) set. But, as well as I know, Happy will report conflicts on PTS grammar given > above, i. e. Happy cannot prove its unambiguity. Also, Happy and Alex cannot pretty-print. And Happy > and Alex don't allow supplying CFG on the fly. > > * Package "earley". Handle arbitrary CFGs, including left-recursive. This is good thing. It seems CFG > can be supplied in runtime. This is good thing, too. Gives all parse trees, thus we can verify that > count of parse trees equals to 1. This is good thing, too. Unfortunately, earley cannot verify CFS's > unambiguity before supplying input. Also, earley doesn't support pretty-printing. > > * PEG libraries. Will not go, I want CFGs. > > * I searched on Hackage reversible parsing libraries. Unfortunately, none of them guarantee > reversibility. I. e. it is very easy to fool these libraries and create parsers and printers not > satisfying equations I gave above. Also, this libraries doesn't have other features I mentioned > > * http://augeas.net/ is very cool project. Unlike nearly everything I found in internet, Augeas > provides guaranteed reversible parsing and pretty-printing (!!!!!). Unfortunately, set of supported > target languages is very limited. Regular languages are supported. And some very limited set of CFGs > is supported. For example, it is possible to construct parser for JSON. But parser for Pascal seems > impossible. Augeas not designed for parsing programming languages. Only simple configuration > languages like JSON, XML, etc. Mutually recursive nonterminals are not supported. Also, Augeas > provides C API, not Haskell one. > > * https://www.brics.dk/xsugar.html is very good. It provides guaranteed reversible translation > between arbitrary language and XML. And XSugar even verifies unambiguity of the CFG using some > sophisticated algorithm. Unfortunately, this algorithm still cannot prove unambiguity of PTS grammar > given above. Also, XSugar is not Haskell library. It is standalone Java app. So, I need to convert > some language to XML, then load this XML to my Haskell program and parse. Also, there is similar lib > https://www.brics.dk/Xact.html from same author, but it is for Java, not for Haskell. > > I was able to find only 2 projects, which do guaranteed reversible parsing: mentioned Augeas and > XSugar/Xact. Unfortunately, both are not for Haskell. And both cannot prove unambiguity for my PTS > grammar. > > So, please tell me about solution. Or give advice how to write one. > > Also, let me describe my experience with various algorithms for checking ambiguity of grammar. > > 1. Try to construct LR(1) table. If there is no conflicts, then the grammar is unambiguous. It seems > this is algorithm used by bison and happy. Unfortunately it is too weak and cannot prove unambiguity > of my PTS grammar. > 2. Try to construct LR(k) table. This algorithm is stronger than LR(1). I was unable to find > implementation of this algorithm in any language. I don't want to write such algorithm. > 3. Schmitz's algorithm. http://www.lsv.fr/~schmitz/pub/expamb.pdf . Even stronger than LR(k). I > downloaded his bison fork. Unfortunately this bison fork can prove unambiguity for same set of > grammars original bison can (i. e. LR(1)). I. e. it seems Schmitz did not implemented his algorithm. > I don't want to implement his algorithm either. > 4. Horizontal and vertical ambiguity checking. https://www.brics.dk/grammar/kruse.pdf . This is > algorithm used in XSugar. Unfortunately, it doesn't handle my PTS grammar. > 5. Brute force up to some limit. Doesn't give unambiguity guarantee. But I like it, and I will use > it if I don't find anything else. It is the only algorithm which can handle my PTS grammar (and > give enough amount of guarantee), not counting LR(k) and Schmitz's algorithm (I was not able to find > implementations of both). > > I will try to write tool I want, I will write about my progress to this list. > > == > Askar Safin > https://github.com/safinaskar > _______________________________________________ > 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 jack at jackkelly.name Mon Jan 4 19:55:49 2021 From: jack at jackkelly.name (jack at jackkelly.name) Date: Mon, 04 Jan 2021 19:55:49 GMT Subject: [Haskell-cafe] How to do reversible parsing? In-Reply-To: <5c12b611-a469-a23d-94c6-0206caed6bd5@rogers.com> References: <5c12b611-a469-a23d-94c6-0206caed6bd5@rogers.com> <1609631960.590531545@f720.i.mail.ru> Message-ID: <89f50774abc4a2a1dbbfdfa7e7754832@jackkelly.name> I poked a bit at this problem late last year[1][2]. I tried to go all the way to an abstraction for monoidal functors, but that might have been aiming too high. Instead, it could be worthwhile to create subclasses of Invariant[3] which stand in for Applicative/Divisible and Alternative/Decidable (and probably their unitless superclasses also). This would give you something like Pickler Combinators[4] on a foundation that looks a bit more like normal Applicative parsers. The other thing I looked at last year was profunctors `P a a` where you use the same type variable in both positions. Instead of following the "monadic profunctors" work of Xia, Orchard, and Wang[5], I had some interesting discussions with Tom Ellis about expanding the hierarchy of the `product-profunctors` package[6][7][8]. (Which I really should revisit and help tie off.) [1]: http://jackkelly.name/blog/archives/2020/08/19/abstracting_over_applicative_alternative_divisible_and_decidable [2]: http://jackkelly.name/blog/archives/2020/11/03/profunctor_decoders_optical_decoders [3]: https://hackage.haskell.org/package/invariant [4]: https://www.microsoft.com/en-us/research/wp-content/uploads/2004/01/picklercombinators.pdf [5]: https://poisson.chat/esop19/composing-bidir-prog-monadically.pdf [6]: https://github.com/tomjaguarpaw/product-profunctors/issues/51 [7]: https://github.com/tomjaguarpaw/product-profunctors/pull/53 [8]: https://github.com/tomjaguarpaw/product-profunctors/pull/54 HTH, -- Jack January 5, 2021 4:23 AM, "Mario" wrote: > That's one ambitious research program you've taken on. I'm not aware of > any complete solution, nor even anything close to it. I can only provide > a couple of potentially useful pieces. I'm the author of the > grammatical-parsers and construct Haskell libraries. The former can > handle left-recursive grammars, the latter is bidirectional. I hope you > can find some inspiration there. > > [1] http://hackage.haskell.org/package/grammatical-parsers > [2] http://hackage.haskell.org/package/construct > > On 2021-01-02 6:59 p.m., Askar Safin via Haskell-Cafe wrote: > >> Hi. How to do deterministic reversible parsing in Haskell? Please, point me to some libs or tools. >> Or give some advice on how to write such lib or tool. (Also, I am interested in solutions for C or >> C++.) >> >> Now let me explain my task in detail. >> >> I am interested in formal math. I am going to develop various proof checkers. In particular, I want >> to develop my PTS checker ( https://en.wikipedia.org/wiki/Pure_type_system ). Here is example of >> existing PTS checker: http://web.archive.org/web/20180924133846/http://www.cs.kun.nl/~janz/yarrow . >> Here is example of input this checker accepts (taken from manual): >> >> Var (+) : Nat -> Nat -> Nat >> Def double := \x:Nat. x+x >> Def S := (+) one >> >> Also, I want to develop something similar to Isabelle ( https://isabelle.in.tum.de ). Example of >> Isabelle input: https://isabelle.in.tum.de/dist/library/HOL/HOL/HOL.html . >> >> Also, I am going to write converters between various languages. For example, between input for some >> existing PTS checker and my PTS checker. >> >> In short, I want to write lot of parsers and pretty-printers for various languages. And thus I need >> some parsing solution. >> >> The solution should have the following features: >> >> 1. The parsing should be divided into lexing and parsing. I. e. usual lex + yacc model. Parsing >> should >> be done using usual context-free grammars (CFGs). Left-recursive grammars should be supported (this >> leaves out parser combinator libraries). All languages I am going to deal with fit this model. I. >> e. >> I will deal with simple to parse languages, such as Pascal. Not complex ones, like C or C++. >> >> 2. Parsing should be deterministic. I. e. parser should check that CFG is unambiguous. Yes, I know >> that this task is impossible to do on Turing machine. But at very least some partial solution will >> go. For example, some algorithm, which will check that some reasonable set of CFGs is >> deterministic. >> Or even brute force up to some limit will go. (Yes, this will not give absolutely correct results, >> but this will go.) This is example of grammar for PTS in one of my checkers (start symbol is t0): >> >> t1000 = id >> t1000 = "(" t0")" >> t999 = t999 t1000 >> t3 = t4 "::" t3 >> t3 = "%" id "::" t0 "." t3 >> t0 = "!!" id "::" t0 "." t0 >> t1 = t2 "==>" t1 >> t0 = t1 >> t1 = t2 >> t2 = t3 >> t3 = t4 >> t4 = t999 >> t999 = t1000 >> >> If I remember correctly, this grammar is deterministic (checked using brute force up to a limit). >> I want solution which will verify that this grammar is deterministic. >> >> All stages of parsing should be proved as deterministic (i. e. scanner too). >> >> 3. Parsing should be reversible. I. e. pretty-printing should be supported, too. And the tool >> should >> guarantee that parsing and pretty-printing match. Now let me give more precise definition. Let's >> assume we have these functions: >> >> parse :: String -> Maybe X >> print :: X -> Maybe String >> >> As you can see, not every internal representation is printable. This is OK. For example, if >> internal >> representation contains variable names that happen to equal reserved words, then, of course, this >> is >> unprintable representation. >> >> The tool should guarantee that: >> a. Result of parsing should be printable, but printing not necessary should give same string. I. e. >> if "parse s == Just x", then "print x /= Nothing". (But not necessary "print x == Just s".) >> b. Parsing of result of printing should give same representation. I. e. if "print x == Just s", >> then >> "parse s == Just x" >> >> 4. Not only parsing should generate parse tree (i. e. exact representation of derivation), but also >> AST. AST differs from parse tree. For example, AST should not contain braces. I. e. "2 + (3 * 4)" >> and >> "2 + 3 * 4" should give same AST. And the tool should be able parse string to AST and pretty print >> AST back to string. >> >> 5. It should be possible to use CFG not known in compile time. Consider Isabelle language. Here is >> again example of Isabelle text: https://isabelle.in.tum.de/dist/library/HOL/HOL/HOL.html . As you >> can >> see the language is divided into inner language and outer language. Strings in inner language are >> quoted. Outer language can add productions to inner language. Inner language cannot change itself. >> "notation" and "translations" commands add productions to inner language. So inner language is not >> known beforehand, it is created dynamically. There is no need to dynamically create scanner, i. e. >> it should be possible to dynamically create parser (for inner language), but there is no such >> requirement for scanner. Also, parser will not change in the middle of parsing given string. >> >> Again: let's assume I write parser for my Isabelle analog. Scanner and parser for outer language is >> fixed. Scanner for inner language is fixed, too. But parser for inner language is not. I read input >> document and add productions to CFG of inner language on the fly. Every time I add production, >> resulting CFG should be checked for ambiguity. And when I find inner language string in input, I >> process it using just constructed parser for inner language. >> >> -- >> >> Points 2 and 3 are the most important in this list. If there is solution which contains them alone, >> this already will be very good. >> >> Now let me list considered solutions. >> >> * Usual combinator libraries (such as parsec) will not go. They don't work with left-recursive >> CFGs. >> They don't check grammars for ambiguities. They don't do reversible parsing. But they allow >> creating >> language on the fly, and this is good thing. >> >> * Happy and alex will not go. As well as I know Happy can prove unambiguity of some very simple >> grammars >> (i. e. for some set of simple grammars it will not report any conflicts and thus will prove they >> unambiguity). >> It seems this is LR(1) set. But, as well as I know, Happy will report conflicts on PTS grammar >> given >> above, i. e. Happy cannot prove its unambiguity. Also, Happy and Alex cannot pretty-print. And >> Happy >> and Alex don't allow supplying CFG on the fly. >> >> * Package "earley". Handle arbitrary CFGs, including left-recursive. This is good thing. It seems >> CFG >> can be supplied in runtime. This is good thing, too. Gives all parse trees, thus we can verify that >> count of parse trees equals to 1. This is good thing, too. Unfortunately, earley cannot verify >> CFS's >> unambiguity before supplying input. Also, earley doesn't support pretty-printing. >> >> * PEG libraries. Will not go, I want CFGs. >> >> * I searched on Hackage reversible parsing libraries. Unfortunately, none of them guarantee >> reversibility. I. e. it is very easy to fool these libraries and create parsers and printers not >> satisfying equations I gave above. Also, this libraries doesn't have other features I mentioned >> >> * http://augeas.net is very cool project. Unlike nearly everything I found in internet, Augeas >> provides guaranteed reversible parsing and pretty-printing (!!!!!). Unfortunately, set of supported >> target languages is very limited. Regular languages are supported. And some very limited set of >> CFGs >> is supported. For example, it is possible to construct parser for JSON. But parser for Pascal seems >> impossible. Augeas not designed for parsing programming languages. Only simple configuration >> languages like JSON, XML, etc. Mutually recursive nonterminals are not supported. Also, Augeas >> provides C API, not Haskell one. >> >> * https://www.brics.dk/xsugar.html is very good. It provides guaranteed reversible translation >> between arbitrary language and XML. And XSugar even verifies unambiguity of the CFG using some >> sophisticated algorithm. Unfortunately, this algorithm still cannot prove unambiguity of PTS >> grammar >> given above. Also, XSugar is not Haskell library. It is standalone Java app. So, I need to convert >> some language to XML, then load this XML to my Haskell program and parse. Also, there is similar >> lib >> https://www.brics.dk/Xact.html from same author, but it is for Java, not for Haskell. >> >> I was able to find only 2 projects, which do guaranteed reversible parsing: mentioned Augeas and >> XSugar/Xact. Unfortunately, both are not for Haskell. And both cannot prove unambiguity for my PTS >> grammar. >> >> So, please tell me about solution. Or give advice how to write one. >> >> Also, let me describe my experience with various algorithms for checking ambiguity of grammar. >> >> 1. Try to construct LR(1) table. If there is no conflicts, then the grammar is unambiguous. It >> seems >> this is algorithm used by bison and happy. Unfortunately it is too weak and cannot prove >> unambiguity >> of my PTS grammar. >> 2. Try to construct LR(k) table. This algorithm is stronger than LR(1). I was unable to find >> implementation of this algorithm in any language. I don't want to write such algorithm. >> 3. Schmitz's algorithm. http://www.lsv.fr/~schmitz/pub/expamb.pdf . Even stronger than LR(k). I >> downloaded his bison fork. Unfortunately this bison fork can prove unambiguity for same set of >> grammars original bison can (i. e. LR(1)). I. e. it seems Schmitz did not implemented his >> algorithm. >> I don't want to implement his algorithm either. >> 4. Horizontal and vertical ambiguity checking. https://www.brics.dk/grammar/kruse.pdf . This is >> algorithm used in XSugar. Unfortunately, it doesn't handle my PTS grammar. >> 5. Brute force up to some limit. Doesn't give unambiguity guarantee. But I like it, and I will use >> it if I don't find anything else. It is the only algorithm which can handle my PTS grammar (and >> give enough amount of guarantee), not counting LR(k) and Schmitz's algorithm (I was not able to >> find >> implementations of both). >> >> I will try to write tool I want, I will write about my progress to this list. >> >> == >> Askar Safin >> https://github.com/safinaskar >> _______________________________________________ >> 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 simonpj at microsoft.com Mon Jan 4 21:18:00 2021 From: simonpj at microsoft.com (Simon Peyton Jones) Date: Mon, 4 Jan 2021 21:18:00 +0000 Subject: [Haskell-cafe] Nominations close Jan 11th for the Haskell Foundation Board Message-ID: Friends Happy new year! The closing date for self-nominations for membership of the Board of the Haskell Foundation is in just under a week: Monday January 11th 2021 The Haskell Foundation is a new non-profit organisation that seeks to articulate the benefits of functional programming to a broader audience, to erase barriers to entry, and to support Haskell as a solidly reliable basis for mission-critical applications. The Board provides the strategic leadership for the Foundation, including its goals, governance, finances, and staff. Membership of the Board is a key leadership role, not an honorary appointment. The Call for Nominations gives more details. Please do consider nominating yourself, or encouraging a suitable (but perhaps modest) colleague to do so. The HF needs a strong Board, and that means strong nominations. Thanks! Please do forward this message on social media or elsewhere. Simon Peyton Jones -------------- next part -------------- An HTML attachment was scrubbed... URL: From evincarofautumn at gmail.com Mon Jan 4 21:26:08 2021 From: evincarofautumn at gmail.com (Jon Purdy) Date: Mon, 4 Jan 2021 13:26:08 -0800 Subject: [Haskell-cafe] How to do reversible parsing? In-Reply-To: <1609631960.590531545@f720.i.mail.ru> References: <1609631960.590531545@f720.i.mail.ru> Message-ID: You may be interested in the profunctor technique of bidirectional parsing/serialisation, a basic version of which is implemented in the ‘codec’ package: . It was originally intended for binary and textual data formats, but could be used for a conventional textual language as well. I have also used this technique at work to develop a similar library, and found it quite effective & performant once you get the (somewhat delicate) internals correct. As you suggest, it’s generally not feasible to have “encode linearity” (‘decode . encode = id’; printing omits no information from output) and “decode linearity” (‘encode . decode = id’; parsing discards no info from input). However, it’s worth verifying both “encode preservation” (‘encode . decode . encode = encode’; parsing preserves all info that printing does) and “decode preservation” (‘decode . encode . decode = decode’; printing preserves all info that parsing does). On Sat, Jan 2, 2021 at 4:02 PM Askar Safin via Haskell-Cafe < haskell-cafe at haskell.org> wrote: > Hi. How to do deterministic reversible parsing in Haskell? Please, point > me to some libs or tools. > Or give some advice on how to write such lib or tool. (Also, I am > interested in solutions for C or C++.) > > Now let me explain my task in detail. > > I am interested in formal math. I am going to develop various proof > checkers. In particular, I want > to develop my PTS checker ( https://en.wikipedia.org/wiki/Pure_type_system > ). Here is example of > existing PTS checker: > http://web.archive.org/web/20180924133846/http://www.cs.kun.nl/~janz/yarrow/ > . > Here is example of input this checker accepts (taken from manual): > > Var (+) : Nat -> Nat -> Nat > Def double := \x:Nat. x+x > Def S := (+) one > > Also, I want to develop something similar to Isabelle ( > https://isabelle.in.tum.de/ ). Example of > Isabelle input: https://isabelle.in.tum.de/dist/library/HOL/HOL/HOL.html . > > Also, I am going to write converters between various languages. For > example, between input for some > existing PTS checker and my PTS checker. > > In short, I want to write lot of parsers and pretty-printers for various > languages. And thus I need > some parsing solution. > > The solution should have the following features: > > 1. The parsing should be divided into lexing and parsing. I. e. usual lex > + yacc model. Parsing should > be done using usual context-free grammars (CFGs). Left-recursive grammars > should be supported (this > leaves out parser combinator libraries). All languages I am going to deal > with fit this model. I. e. > I will deal with simple to parse languages, such as Pascal. Not complex > ones, like C or C++. > > 2. Parsing should be deterministic. I. e. parser should check that CFG is > unambiguous. Yes, I know > that this task is impossible to do on Turing machine. But at very least > some partial solution will > go. For example, some algorithm, which will check that some reasonable set > of CFGs is deterministic. > Or even brute force up to some limit will go. (Yes, this will not give > absolutely correct results, > but this will go.) This is example of grammar for PTS in one of my > checkers (start symbol is t0): > > t1000 = id > t1000 = "(" t0")" > t999 = t999 t1000 > t3 = t4 "::" t3 > t3 = "%" id "::" t0 "." t3 > t0 = "!!" id "::" t0 "." t0 > t1 = t2 "==>" t1 > t0 = t1 > t1 = t2 > t2 = t3 > t3 = t4 > t4 = t999 > t999 = t1000 > > If I remember correctly, this grammar is deterministic (checked using > brute force up to a limit). > I want solution which will verify that this grammar is deterministic. > > All stages of parsing should be proved as deterministic (i. e. scanner > too). > > 3. Parsing should be reversible. I. e. pretty-printing should be > supported, too. And the tool should > guarantee that parsing and pretty-printing match. Now let me give more > precise definition. Let's > assume we have these functions: > > parse :: String -> Maybe X > print :: X -> Maybe String > > As you can see, not every internal representation is printable. This is > OK. For example, if internal > representation contains variable names that happen to equal reserved > words, then, of course, this is > unprintable representation. > > The tool should guarantee that: > a. Result of parsing should be printable, but printing not necessary > should give same string. I. e. > if "parse s == Just x", then "print x /= Nothing". (But not necessary > "print x == Just s".) > b. Parsing of result of printing should give same representation. I. e. if > "print x == Just s", then > "parse s == Just x" > > 4. Not only parsing should generate parse tree (i. e. exact representation > of derivation), but also > AST. AST differs from parse tree. For example, AST should not contain > braces. I. e. "2 + (3 * 4)" and > "2 + 3 * 4" should give same AST. And the tool should be able parse string > to AST and pretty print > AST back to string. > > 5. It should be possible to use CFG not known in compile time. Consider > Isabelle language. Here is > again example of Isabelle text: > https://isabelle.in.tum.de/dist/library/HOL/HOL/HOL.html . As you can > see the language is divided into inner language and outer language. > Strings in inner language are > quoted. Outer language can add productions to inner language. Inner > language cannot change itself. > "notation" and "translations" commands add productions to inner language. > So inner language is not > known beforehand, it is created dynamically. There is no need to > dynamically create scanner, i. e. > it should be possible to dynamically create parser (for inner language), > but there is no such > requirement for scanner. Also, parser will not change in the middle of > parsing given string. > > Again: let's assume I write parser for my Isabelle analog. Scanner and > parser for outer language is > fixed. Scanner for inner language is fixed, too. But parser for inner > language is not. I read input > document and add productions to CFG of inner language on the fly. Every > time I add production, > resulting CFG should be checked for ambiguity. And when I find inner > language string in input, I > process it using just constructed parser for inner language. > > -- > > Points 2 and 3 are the most important in this list. If there is solution > which contains them alone, > this already will be very good. > > Now let me list considered solutions. > > * Usual combinator libraries (such as parsec) will not go. They don't work > with left-recursive CFGs. > They don't check grammars for ambiguities. They don't do reversible > parsing. But they allow creating > language on the fly, and this is good thing. > > * Happy and alex will not go. As well as I know Happy can prove > unambiguity of some very simple grammars > (i. e. for some set of simple grammars it will not report any conflicts > and thus will prove they unambiguity). > It seems this is LR(1) set. But, as well as I know, Happy will report > conflicts on PTS grammar given > above, i. e. Happy cannot prove its unambiguity. Also, Happy and Alex > cannot pretty-print. And Happy > and Alex don't allow supplying CFG on the fly. > > * Package "earley". Handle arbitrary CFGs, including left-recursive. This > is good thing. It seems CFG > can be supplied in runtime. This is good thing, too. Gives all parse > trees, thus we can verify that > count of parse trees equals to 1. This is good thing, too. Unfortunately, > earley cannot verify CFS's > unambiguity before supplying input. Also, earley doesn't support > pretty-printing. > > * PEG libraries. Will not go, I want CFGs. > > * I searched on Hackage reversible parsing libraries. Unfortunately, none > of them guarantee > reversibility. I. e. it is very easy to fool these libraries and create > parsers and printers not > satisfying equations I gave above. Also, this libraries doesn't have other > features I mentioned > > * http://augeas.net/ is very cool project. Unlike nearly everything I > found in internet, Augeas > provides guaranteed reversible parsing and pretty-printing (!!!!!). > Unfortunately, set of supported > target languages is very limited. Regular languages are supported. And > some very limited set of CFGs > is supported. For example, it is possible to construct parser for JSON. > But parser for Pascal seems > impossible. Augeas not designed for parsing programming languages. Only > simple configuration > languages like JSON, XML, etc. Mutually recursive nonterminals are not > supported. Also, Augeas > provides C API, not Haskell one. > > * https://www.brics.dk/xsugar.html is very good. It provides guaranteed > reversible translation > between arbitrary language and XML. And XSugar even verifies unambiguity > of the CFG using some > sophisticated algorithm. Unfortunately, this algorithm still cannot prove > unambiguity of PTS grammar > given above. Also, XSugar is not Haskell library. It is standalone Java > app. So, I need to convert > some language to XML, then load this XML to my Haskell program and parse. > Also, there is similar lib > https://www.brics.dk/Xact.html from same author, but it is for Java, not > for Haskell. > > I was able to find only 2 projects, which do guaranteed reversible > parsing: mentioned Augeas and > XSugar/Xact. Unfortunately, both are not for Haskell. And both cannot > prove unambiguity for my PTS > grammar. > > So, please tell me about solution. Or give advice how to write one. > > Also, let me describe my experience with various algorithms for checking > ambiguity of grammar. > > 1. Try to construct LR(1) table. If there is no conflicts, then the > grammar is unambiguous. It seems > this is algorithm used by bison and happy. Unfortunately it is too weak > and cannot prove unambiguity > of my PTS grammar. > 2. Try to construct LR(k) table. This algorithm is stronger than LR(1). I > was unable to find > implementation of this algorithm in any language. I don't want to write > such algorithm. > 3. Schmitz's algorithm. http://www.lsv.fr/~schmitz/pub/expamb.pdf . Even > stronger than LR(k). I > downloaded his bison fork. Unfortunately this bison fork can prove > unambiguity for same set of > grammars original bison can (i. e. LR(1)). I. e. it seems Schmitz did not > implemented his algorithm. > I don't want to implement his algorithm either. > 4. Horizontal and vertical ambiguity checking. > https://www.brics.dk/grammar/kruse.pdf . This is > algorithm used in XSugar. Unfortunately, it doesn't handle my PTS grammar. > 5. Brute force up to some limit. Doesn't give unambiguity guarantee. But I > like it, and I will use > it if I don't find anything else. It is the only algorithm which can > handle my PTS grammar (and > give enough amount of guarantee), not counting LR(k) and Schmitz's > algorithm (I was not able to find > implementations of both). > > I will try to write tool I want, I will write about my progress to this > list. > > == > Askar Safin > https://github.com/safinaskar > _______________________________________________ > 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 K.Bleijenberg at lijbrandt.nl Tue Jan 5 12:23:45 2021 From: K.Bleijenberg at lijbrandt.nl (Kees Bleijenberg) Date: Tue, 5 Jan 2021 13:23:45 +0100 Subject: [Haskell-cafe] FW: upload file with ftp Message-ID: <000501d6e35d$9c940ba0$d5bc22e0$@lijbrandt.nl> I want to upload a file with ftp using library Network.FTP.Client. The OS is Windows 64 and ghc version is 8.6.4. This is the code: import System.FilePath.Windows import Network.FTP.Client import qualified Data.ByteString as B .... testFtp :: IO (Either String ()) testFtp = do let host = "copecco" -- this is from my hosts file username = **** pwd = **** ftpDir = "registratie" fileToSend = "globals.pas" -- a test text file putStrLn $ "Connect to " ++ host withFTP host 21 $ \h ftpResponse -> do print ftpResponse if frStatus ftpResponse == Success then do putStrLn "Connected" loginResp <- login h username pwd print loginResp if frStatus loginResp == Success then do putStrLn $ "Change directory to " ++ ftpDir cwdResp <- cwd h ftpDir print cwdResp if frStatus cwdResp == Success then do putStrLn "Read file from disk" let ftpFn = takeFileName fileToSend fileContents <- B.readFile fileToSend putStrLn $ "File size: " ++ show (B.length fileContents) ++ " bytes" stor h ftpFn fileContents TI return $ Right () else return $ Left $ "Ftp error cwd. Code: " ++ show (frCode ftpResponse) else return $ Left $ "Ftp error login. Code: " ++ show (frCode ftpResponse) else return $ Left $ "Connect to host " ++ host ++ " failed. Code: " ++ show (frCode ftpResponse) This is the response: Connect to copecco 220 (vsFTPd 3.0.2) Connected 230 Login successful. Change directory to registratie 250 Directory successfully changed. Read file File size: 27015 bytes *** Exception: Network.Socket.connect: : failed (Connection timed out (WSAETIMEDOUT)) Everything works fine until the stor commmand. When I upload the same file with another ftp client program everything works (no permission problems). What is wrong and how do I get the result codes for the stor command? Kees From allbery.b at gmail.com Tue Jan 5 12:48:51 2021 From: allbery.b at gmail.com (Brandon Allbery) Date: Tue, 5 Jan 2021 07:48:51 -0500 Subject: [Haskell-cafe] FW: upload file with ftp In-Reply-To: <000501d6e35d$9c940ba0$d5bc22e0$@lijbrandt.nl> References: <000501d6e35d$9c940ba0$d5bc22e0$@lijbrandt.nl> Message-ID: At a guess, you're using a modern FTP client that defaults to passive mode for compatibility with firewalls, and you'll need to check the docs to see how to do passive mode with Network.Client.FTP. On Tue, Jan 5, 2021 at 7:24 AM Kees Bleijenberg wrote: > I want to upload a file with ftp using library Network.FTP.Client. > The OS is Windows 64 and ghc version is 8.6.4. > > This is the code: > > import System.FilePath.Windows > import Network.FTP.Client > import qualified Data.ByteString as B > .... > testFtp :: IO (Either String ()) > testFtp = do > let host = "copecco" -- this is from my hosts file > username = **** > pwd = **** > ftpDir = "registratie" > fileToSend = "globals.pas" -- a test text file > putStrLn $ "Connect to " ++ host > withFTP host 21 $ \h ftpResponse -> do > print ftpResponse > if frStatus ftpResponse == Success > then do > putStrLn "Connected" > loginResp <- login h username pwd > print loginResp > if frStatus loginResp == Success > then do > putStrLn $ "Change directory to " ++ ftpDir > cwdResp <- cwd h ftpDir > print cwdResp > if frStatus cwdResp == Success > then do > putStrLn "Read file from disk" > let ftpFn = takeFileName fileToSend > fileContents <- B.readFile fileToSend > putStrLn $ "File size: " ++ show > (B.length fileContents) ++ " bytes" > stor h ftpFn fileContents TI > return $ Right () > else return $ Left $ "Ftp error cwd. Code: " ++ > show (frCode ftpResponse) > else return $ Left $ "Ftp error login. Code: " ++ show > (frCode ftpResponse) > else return $ Left $ "Connect to host " ++ host ++ " failed. > Code: > " ++ show (frCode ftpResponse) > > This is the response: > Connect to copecco > > 220 (vsFTPd 3.0.2) > > Connected > > 230 Login successful. > > Change directory to registratie > > 250 Directory successfully changed. > > Read file > > File size: 27015 bytes > > *** Exception: Network.Socket.connect: : failed (Connection > timed out (WSAETIMEDOUT)) > > Everything works fine until the stor commmand. > When I upload the same file with another ftp client program everything > works > (no permission problems). > > What is wrong and how do I get the result codes for the stor command? > > Kees > > > _______________________________________________ > 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 allbery.b at gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From K.Bleijenberg at lijbrandt.nl Tue Jan 5 15:54:56 2021 From: K.Bleijenberg at lijbrandt.nl (Kees Bleijenberg) Date: Tue, 5 Jan 2021 16:54:56 +0100 Subject: [Haskell-cafe] upload file with ftp Message-ID: <000201d6e37b$1d43bf30$57cb3d90$@lijbrandt.nl> Hi Brandon, The ftp-client I use (total commander) does not use passive mode. I changed the host to another server. And now I do not get an exception, no error messages, but nothing is uploaded. Unfortunately is ‘working in passive mode’ not so easy (at least not to me). After login I send the ‘pasv’ command and I get back a IP address and a port (I assume). Do I have to create a new connection with a handle to this new port for the stor command? I don’t know how to do that in network.ftp.client. A hint or better a working example would be nice. Kees Van: Brandon Allbery [mailto:allbery.b at gmail.com] Verzonden: dinsdag 5 januari 2021 13:49 Aan: Kees Bleijenberg CC: haskell-cafe Onderwerp: Re: [Haskell-cafe] FW: upload file with ftp At a guess, you're using a modern FTP client that defaults to passive mode for compatibility with firewalls, and you'll need to check the docs to see how to do passive mode with Network.Client.FTP. On Tue, Jan 5, 2021 at 7:24 AM Kees Bleijenberg > wrote: I want to upload a file with ftp using library Network.FTP.Client. The OS is Windows 64 and ghc version is 8.6.4. This is the code: import System.FilePath.Windows import Network.FTP.Client import qualified Data.ByteString as B .... testFtp :: IO (Either String ()) testFtp = do let host = "copecco" -- this is from my hosts file username = **** pwd = **** ftpDir = "registratie" fileToSend = "globals.pas" -- a test text file putStrLn $ "Connect to " ++ host withFTP host 21 $ \h ftpResponse -> do print ftpResponse if frStatus ftpResponse == Success then do putStrLn "Connected" loginResp <- login h username pwd print loginResp if frStatus loginResp == Success then do putStrLn $ "Change directory to " ++ ftpDir cwdResp <- cwd h ftpDir print cwdResp if frStatus cwdResp == Success then do putStrLn "Read file from disk" let ftpFn = takeFileName fileToSend fileContents <- B.readFile fileToSend putStrLn $ "File size: " ++ show (B.length fileContents) ++ " bytes" stor h ftpFn fileContents TI return $ Right () else return $ Left $ "Ftp error cwd. Code: " ++ show (frCode ftpResponse) else return $ Left $ "Ftp error login. Code: " ++ show (frCode ftpResponse) else return $ Left $ "Connect to host " ++ host ++ " failed. Code: " ++ show (frCode ftpResponse) This is the response: Connect to copecco 220 (vsFTPd 3.0.2) Connected 230 Login successful. Change directory to registratie 250 Directory successfully changed. Read file File size: 27015 bytes *** Exception: Network.Socket.connect: : failed (Connection timed out (WSAETIMEDOUT)) Everything works fine until the stor commmand. When I upload the same file with another ftp client program everything works (no permission problems). What is wrong and how do I get the result codes for the stor command? Kees _______________________________________________ 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 allbery.b at gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From jo at durchholz.org Tue Jan 5 19:08:34 2021 From: jo at durchholz.org (Joachim Durchholz) Date: Tue, 5 Jan 2021 20:08:34 +0100 Subject: [Haskell-cafe] upload file with ftp In-Reply-To: <000201d6e37b$1d43bf30$57cb3d90$@lijbrandt.nl> References: <000201d6e37b$1d43bf30$57cb3d90$@lijbrandt.nl> Message-ID: <910dba5f-1488-7435-c202-5b66849d6c15@durchholz.org> Am 05.01.21 um 16:54 schrieb Kees Bleijenberg: > Unfortunately is ‘working in passive mode’ not so easy (at least not to > me). After login I send the ‘pasv’ command and I get back a IP address > and a port (I assume). Do I have to create a new connection with a > handle to this new port for the stor command? Yes. >  I don’t know how to do that in network.ftp.client. If network.ftp.client does not support that out of the box, you'll either have to find another library or add PASV support to it. My knowledge of the FTP protocol is pretty rusty, but I believe you the model after PASV is that you continue using normal commands but the data transfers happen over the other connection. I'd watch out for how the protocol marks the beginning and end of a data stream (it's not a single connection anymore so you lose the sequencing guarantees of TCP packets; I'd assume they either send a special packet on the data connection, or they transmit the file sizes via the normal channel). However, I can't avoid wondering why anybody would want to use the FTP protocol at all. It's so unsafe, so bottleneck-endangered, the only reason to do that would be interfacing with existing FTP servers, and even these are being phased out in favor of HTTPS, with POST for uploads. (I'm not questioning the validity of your use case, just wondering how such a use case can come up in today's world.) Regards, Jo From allbery.b at gmail.com Tue Jan 5 19:14:06 2021 From: allbery.b at gmail.com (Brandon Allbery) Date: Tue, 5 Jan 2021 14:14:06 -0500 Subject: [Haskell-cafe] upload file with ftp In-Reply-To: <910dba5f-1488-7435-c202-5b66849d6c15@durchholz.org> References: <000201d6e37b$1d43bf30$57cb3d90$@lijbrandt.nl> <910dba5f-1488-7435-c202-5b66849d6c15@durchholz.org> Message-ID: In normal mode the server opens a connection to the FTP client; in PASV mode the client instead opens a connection to the server, so it'll work through a firewall. On Tue, Jan 5, 2021 at 2:09 PM Joachim Durchholz wrote: > Am 05.01.21 um 16:54 schrieb Kees Bleijenberg: > > Unfortunately is ‘working in passive mode’ not so easy (at least not to > > me). After login I send the ‘pasv’ command and I get back a IP address > > and a port (I assume). Do I have to create a new connection with a > > handle to this new port for the stor command? > > Yes. > > > I don’t know how to do that in network.ftp.client. > > If network.ftp.client does not support that out of the box, you'll > either have to find another library or add PASV support to it. > > My knowledge of the FTP protocol is pretty rusty, but I believe you the > model after PASV is that you continue using normal commands but the data > transfers happen over the other connection. > I'd watch out for how the protocol marks the beginning and end of a data > stream (it's not a single connection anymore so you lose the sequencing > guarantees of TCP packets; I'd assume they either send a special packet > on the data connection, or they transmit the file sizes via the normal > channel). > > However, I can't avoid wondering why anybody would want to use the FTP > protocol at all. It's so unsafe, so bottleneck-endangered, the only > reason to do that would be interfacing with existing FTP servers, and > even these are being phased out in favor of HTTPS, with POST for uploads. > (I'm not questioning the validity of your use case, just wondering how > such a use case can come up in today's world.) > > Regards, > Jo > _______________________________________________ > 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 allbery.b at gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From K.Bleijenberg at lijbrandt.nl Wed Jan 6 09:42:20 2021 From: K.Bleijenberg at lijbrandt.nl (Kees Bleijenberg) Date: Wed, 6 Jan 2021 10:42:20 +0100 Subject: [Haskell-cafe] upload file with ftp In-Reply-To: <910dba5f-1488-7435-c202-5b66849d6c15@durchholz.org> References: <000201d6e37b$1d43bf30$57cb3d90$@lijbrandt.nl> <910dba5f-1488-7435-c202-5b66849d6c15@durchholz.org> Message-ID: <000001d6e410$3a4e2da0$aeea88e0$@lijbrandt.nl> Joachim, Brandon, After investigating the source for the store command in Network.FTP.Client (https://hackage.haskell.org/package/ftp-client-0.5.1.4/docs/Network-FTP-Client.html) I found that the stor command already sets the connection in passive mode. I tried my original code on Linux and everything works fine. So probably the problem is (as always) Windows. A few years ago I tried some Haskell ftp client libs. On Windows they all raised access violations as soon as I connected to a server. Now, a few years later the Network library has improved (not sure) and I tried it again. Big improvements: Login, get a list of files, change directory works fine but stor does not. So there is still no working FTP-client lib for Haskell (I think). I know FTP is not secure but it is easy to use. Almost everybody uses it for uploading files to a website. Writing code for uploading a file with http(s)in Haskell is a lot more work than ftp and I wonder whether the https stuff will work on Windows. And with http(s) you have to write an extra server side program (php) to save the uploaded file, return error messages... I just want a simple way to upload a generated file to my private website. Until now I upload a file by running a program within my Haskell program. That ftp-program sends a file with ftp to a server. The ftp-program is written in Delphi/Lazarus. Thanks for your help. Kees -----Oorspronkelijk bericht----- Van: Haskell-Cafe [mailto:haskell-cafe-bounces at haskell.org] Namens Joachim Durchholz Verzonden: dinsdag 5 januari 2021 20:09 Aan: haskell-cafe at haskell.org Onderwerp: Re: [Haskell-cafe] upload file with ftp Am 05.01.21 um 16:54 schrieb Kees Bleijenberg: > Unfortunately is ‘working in passive mode’ not so easy (at least not to > me). After login I send the ‘pasv’ command and I get back a IP address > and a port (I assume). Do I have to create a new connection with a > handle to this new port for the stor command? Yes. > I don’t know how to do that in network.ftp.client. If network.ftp.client does not support that out of the box, you'll either have to find another library or add PASV support to it. My knowledge of the FTP protocol is pretty rusty, but I believe you the model after PASV is that you continue using normal commands but the data transfers happen over the other connection. I'd watch out for how the protocol marks the beginning and end of a data stream (it's not a single connection anymore so you lose the sequencing guarantees of TCP packets; I'd assume they either send a special packet on the data connection, or they transmit the file sizes via the normal channel). However, I can't avoid wondering why anybody would want to use the FTP protocol at all. It's so unsafe, so bottleneck-endangered, the only reason to do that would be interfacing with existing FTP servers, and even these are being phased out in favor of HTTPS, with POST for uploads. (I'm not questioning the validity of your use case, just wondering how such a use case can come up in today's world.) Regards, Jo _______________________________________________ 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 safinaskar at mail.ru Wed Jan 6 11:48:58 2021 From: safinaskar at mail.ru (=?UTF-8?B?QXNrYXIgU2FmaW4=?=) Date: Wed, 06 Jan 2021 14:48:58 +0300 Subject: [Haskell-cafe] =?utf-8?q?How_to_do_reversible_parsing=3F?= In-Reply-To: <2933bd03-6c59-495a-d464-149fff943dc0@htwk-leipzig.de> References: <2933bd03-6c59-495a-d464-149fff943dc0@htwk-leipzig.de> Message-ID: <1609933738.12654447@f320.i.mail.ru> > Rendell and Ostermann, > Invertible syntax descriptions, > Haskell Symposium '10 > https://doi.org/10.1145/1863523.1863525 > https://hackage.haskell.org/package/invertible-syntax Hi. Thanks a lot for answer. This package does not build with ghc 8.8.4, because it did not implemented MonadFail proposal. This shows that (unfortunately) nobody cares that reversible parsing actually works. But I was able to build the package with ghc 8.0.1. I tried to break the package, i. e. I tried to create grammar such that parsing and printing will not match. I was unable to do this, so it seems the package really guarantees reversible parsing. It seems I overlooked it when I searched Hackage. I will probably use this package. But it doesn't check grammars for ambiguity. I will probably use this package together with my brute force algorithm. >Perhaps you don't even need to pretty-print? I need printing. == Askar Safin https://github.com/safinaskar From johannes.waldmann at htwk-leipzig.de Wed Jan 6 17:03:06 2021 From: johannes.waldmann at htwk-leipzig.de (Johannes Waldmann) Date: Wed, 6 Jan 2021 18:03:06 +0100 Subject: [Haskell-cafe] command substitution in ghci? Message-ID: <5bbb5c52-69d1-0412-8264-8f953e2e2b6f@htwk-leipzig.de> In a ghci session, I have an IO action that returns a file name, and then I want to :script that file. (The action could also be made to return the contents.) Cf. Bash has $(foo) to allow the output of a command to replace the command itself. See Bash manual 3.5.4 "Command Substitution" - $(command) and $(< file). We do have a work-around, since this is being called from an elisp program. This is just about a micro-optimisation of not calling ghci twice. https://github.com/tidalcycles/Tidal/issues/743 And the whole thing is a work-around for ghc and ghc-pkg not agreeing on the use of environment files (I think) - J. From safinaskar at mail.ru Wed Jan 6 19:14:16 2021 From: safinaskar at mail.ru (=?UTF-8?B?QXNrYXIgU2FmaW4=?=) Date: Wed, 06 Jan 2021 22:14:16 +0300 Subject: [Haskell-cafe] =?utf-8?q?How_to_do_reversible_parsing=3F?= In-Reply-To: <2933bd03-6c59-495a-d464-149fff943dc0@htwk-leipzig.de> References: <2933bd03-6c59-495a-d464-149fff943dc0@htwk-leipzig.de> Message-ID: <1609960456.862009466@f133.i.mail.ru> > https://hackage.haskell.org/package/invertible-syntax Hi. My first impression about this package was wrong. The package doesn't check that parsing is deterministic. Parser returns list of results instead of just one result. I. e. we cannot be sure about determinism before actual parsing. So, this package will not go == Askar Safin https://github.com/safinaskar From jo at durchholz.org Wed Jan 6 20:04:58 2021 From: jo at durchholz.org (Joachim Durchholz) Date: Wed, 6 Jan 2021 21:04:58 +0100 Subject: [Haskell-cafe] upload file with ftp In-Reply-To: <000001d6e410$3a4e2da0$aeea88e0$@lijbrandt.nl> References: <000201d6e37b$1d43bf30$57cb3d90$@lijbrandt.nl> <910dba5f-1488-7435-c202-5b66849d6c15@durchholz.org> <000001d6e410$3a4e2da0$aeea88e0$@lijbrandt.nl> Message-ID: <599efba6-f048-0897-d69a-6dbf04af7f1e@durchholz.org> Am 06.01.21 um 10:42 schrieb Kees Bleijenberg: > Joachim, Brandon, > > After investigating the source for the store command in Network.FTP.Client (https://hackage.haskell.org/package/ftp-client-0.5.1.4/docs/Network-FTP-Client.html) I found that the stor command already sets the connection in passive mode. I tried my original code on Linux and everything works fine. So probably the problem is (as always) Windows. Unlikely it's Windows' network stack - there is nothing special about an outgoing FTP connection. > A few years ago I tried some Haskell ftp client libs. On Windows they all raised access violations as soon as I connected to a server. Now, a few years later the Network library has improved (not sure) and I tried it again. Big improvements: Login, get a list of files, change directory works fine but stor does not. So there is still no working FTP-client lib for Haskell (I think). Or the difference is that you have a different firewall setup. Possibly caused by Windows itself, or maybe some antivirus product. You should be able to test this hypothesis by using telnet or some other program that allows you to open any port. Access violations are typically the result of opening a reserved port without proper permissions. > I know FTP is not secure but it is easy to use. It is not, actually. You have to worry about: * passive vs. normal mode, * text vs. binary mode (text mode is obsolete since more than a decade), * directory listings being misrepresented because * encoding issues * some FTP server with its own idea of how to represent these (manageable with command-line clients, GUI clients may fall over) * flipped bits (TCP does only so much here), * aborted transfers (supported but not with client/server mismatch) * security: your FTP password is visible to anybody in the same network segment (including malware they might have caught). rsync, sftp and scp eliminate every single one of these worries. > Almost everybody uses it for uploading files to a website. Actually the vast majority of file uploads go through HTTP POST nowadays. It's been over a decade since I have even seen something with an FTP upload, though I guess very old services might still stick to it just because upgrading is a pretty big step for all parties involved. My knee-jerk reaction to an FTP upload site: Big Red Flag. Admins who ignore basic security advice, like not offering a server site that forces you to send passwords in the clear. (sftp is NOT affected by this. Protocol-wise, it's a totally different technology.) > Writing code for uploading a file with http(s)in Haskell is a lot more work than ftp and I wonder whether the https stuff will work on Windows. Between Linux and Windows, HTTPS does not have any significant differences. Hmm... well, okay, it is different if you want to use the system's proxy settings and certificate store. I don't know how that works, so I can't say much about this. However, I believe the bigger difference is between HTTP and HTTPS. Setting up the certificates and doing the connection handshake is a pretty complicated stuff. I don't know good the Haskell https libraries are at this; at least for Java, I can report that the default libraries do work but aren't exactly good at controlling the connection parameters or accurately reporting error situations. (That's why everybody uses Apache HttpClient, except the people who wrote the legacy app I'm tasked with maintaining and improving... well, if everything worked, there wouldn't interesting work, so there :-) ) > And with http(s) you have to write an extra server side program (php) to save the uploaded file, return error messages... > I just want a simple way to upload a generated file to my private website. Use the SSH-based protocols then - either sftp/ssh (server side is the same, but without root access setup can be complicated) or rsync (almost universally available, and setting up an rsync server should be simple). Caveat: I don't know whether Haskell libraries for any of these exist. BTW dealing with HTTP POST is easier than setting up your own server. Been there, done that, on both sides. > Until now I upload a file by running a program within my Haskell program. That ftp-program sends a file with ftp to a server. The ftp-program is written in Delphi/Lazarus. In that case, you'll be better off just falling back to rsync. Expect to spend an afternoon sifting through the options if you want to transfer entire directories. If your server doesn't know how to handle rsync and you can't isntall it: Use a different provider. FTP is generally the worst option, in oh so many ways. Really. Scout's honor. Regards, Jo From johannes.waldmann at htwk-leipzig.de Wed Jan 6 20:26:14 2021 From: johannes.waldmann at htwk-leipzig.de (Johannes Waldmann) Date: Wed, 6 Jan 2021 21:26:14 +0100 Subject: [Haskell-cafe] How to do reversible parsing? In-Reply-To: <1609960456.862009466@f133.i.mail.ru> References: <2933bd03-6c59-495a-d464-149fff943dc0@htwk-leipzig.de> <1609960456.862009466@f133.i.mail.ru> Message-ID: <1cf92d73-29a5-67f5-ba12-d4e03b30c82b@htwk-leipzig.de> > (unfortunately) nobody cares that reversible parsing actually works. Well what about https://github.com/kolmodin/binary/blob/master/tests/QC.hs#L50 is this not "caring for reversibility"? (in a similar context) > we cannot be sure about determinism Assume you come up with a deterministic grammar for Isabelle (say). How do you want to be sure it is the right one? Would it not be a good idea to use the given grammar (extract from sources of tools, e.g., https://isabelle-dev.sketis.net/source/isabelle/browse/default/src/Pure/Isar/parse_spec.ML - this is already a combinator parser? or from specification/documentation, e.g., http://isabelle.in.tum.de/dist/Isabelle2020/doc/isar-ref.pdf ?) Best regards, J. NB: full Isabelle seems quite the challenge to parse: isar-ref 8.4.5 "... parsing may be ambiguous. Isabelle lets the Earley parser enumerate all possible parse trees... Terms that cannot be type-checked are filtered out. Unlike regular type reconstruction, ... the filtering stage only ..." From safinaskar at mail.ru Wed Jan 6 22:53:56 2021 From: safinaskar at mail.ru (=?UTF-8?B?QXNrYXIgU2FmaW4=?=) Date: Thu, 07 Jan 2021 01:53:56 +0300 Subject: [Haskell-cafe] =?utf-8?q?How_to_do_reversible_parsing=3F?= In-Reply-To: <1cf92d73-29a5-67f5-ba12-d4e03b30c82b@htwk-leipzig.de> References: <2933bd03-6c59-495a-d464-149fff943dc0@htwk-leipzig.de> <1609960456.862009466@f133.i.mail.ru> <1cf92d73-29a5-67f5-ba12-d4e03b30c82b@htwk-leipzig.de> Message-ID: <1609973636.24357474@f142.i.mail.ru> Hi. > How do you want to be sure it is the right one? I don't want to parse Isabelle code. I want to create language similar to Isabelle. == Askar Safin https://github.com/safinaskar From safinaskar at mail.ru Wed Jan 6 23:08:25 2021 From: safinaskar at mail.ru (=?UTF-8?B?QXNrYXIgU2FmaW4=?=) Date: Thu, 07 Jan 2021 02:08:25 +0300 Subject: [Haskell-cafe] =?utf-8?q?How_to_do_reversible_parsing=3F?= In-Reply-To: <1609631960.590531545@f720.i.mail.ru> References: <1609631960.590531545@f720.i.mail.ru> Message-ID: <1609974505.896590352@f550.i.mail.ru> Hi. How to do reversible converting between parse tree and AST? My final task can be thought as the following reversible computation: stream of chars <---> stream of tokens <---> parse tree <---> AST On first piece (chars <---> tokens): I will probably just give up on reversible lexing, so the problem is gone. :) I will write separate lexer and printer. On second piece (tokens <---> parse tree): printing is easy. For parsing I will use package "Earley" from Hackage. And I will use brute force to ensure unambiguity. On third piece (parse tree <---> AST): it seems to be last remaining piece. I don't know how to get both translators in the same time. Consider usual arithmetic language, i. e. a * (b + c). This is how parse tree may look: data Term = Id Id | Braces LBrace Expr RBrace data Product = Term Term | Times Product Times Term data Expr = Product Product | Plus Expr Plus Product As you can see this data types are direct mapping of grammar. And this is how corresponding AST looks: data AExpr = AId Id | ATimes AExpr AExpr | APlus AExpr AExpr Is there some way to simultaneously write translators in both directions? == Askar Safin https://github.com/safinaskar From P.Achten at cs.ru.nl Fri Jan 8 08:09:17 2021 From: P.Achten at cs.ru.nl (Peter Achten) Date: Fri, 8 Jan 2021 09:09:17 +0100 Subject: [Haskell-cafe] [TFP'21] final call for papers: Trends in Functional Programming 2021, 17-19 February (online event with Lambda Days 2021 & TFPIE 2021) Message-ID: <8dc2c60b-0006-bd26-e554-3ce78e1c18be@cs.ru.nl> -------------------------------------------------------------------------                       Final call for papers         22nd Symposium on Trends in Functional Programming                           tfp2021.org                    *deadline: January 15 2021* ------------------------------------------------------------------------- Did you miss the deadline to submit a paper to Trends in Functional Programming http://tfp2021.org/? No worries -- it's not too late! Submission is open until January 15th 2021, for a presentation slot at the event and post-symposium reviewing. 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. * TFP offers a supportive reviewing process designed to help less experienced   authors succeed, with two rounds of review, both before and after the   symposium itself. Authors have an opportunity to address reviewers' concerns   before final decisions on publication in the proceedings. * TFP offers two "best paper" awards, the John McCarthy award for best paper,   and the David Turner award for best student paper. * TFP is co-located with Lambda Days in beautiful Krakow. Lambda Days is a vibrant   developer conference with hundreds of attendees and a lively programme of talks on   functional programming in practice. Due to the covid pandemic, the event is online   with a lot of attention to interaction and getting to socialize with the community. Important Dates --------------- Submission deadline for pre-symposium review:   20th November, 2020  -- passed -- Submission deadline for draft papers:           15th January, 2021 Symposium dates:                                17-19th February, 2021 Visit http://tfp2021.org/ for more information. From andrei.paskevich at lri.fr Fri Jan 8 17:52:46 2021 From: andrei.paskevich at lri.fr (Andrei Paskevich) Date: Fri, 8 Jan 2021 18:52:46 +0100 Subject: [Haskell-cafe] F-IDE 2021 - 2nd Call for Papers Message-ID: An embedded and charset-unspecified text was scrubbed... Name: not available URL: From kindaro at gmail.com Sat Jan 9 08:38:00 2021 From: kindaro at gmail.com (Ignat Insarov) Date: Sat, 9 Jan 2021 13:38:00 +0500 Subject: [Haskell-cafe] A quick question about distribution of finite maps. Message-ID: Hello! Finite maps from `"containers" Data.Map` look like they may form a Cartesian closed category. So it makes sense to ask if the rule _α ⇸ (β ⇸ γ) ≡ ⟨α; β⟩ ⇸ γ ≡ ⟨β; α⟩ ⇸ γ ≡ β ⇸ (α ⇸ γ)_ that holds in such categories does hold for finite maps. Note that, a map being a functor, this also may be seen as _f (g α) ≡ g (f α)_, which would work if maps were `Distributive` [1]. It looks to me as though the following definition might work: distribute = unionsWith union . mapWithKey (fmap . singleton) — And it works on simple examples. _(I checked the law `distribute ∘ distribute ≡ id` — it appears to be the only law required.)_ Is this definition correct? Is it already known and defined elsewhere? [1]: https://hackage.haskell.org/package/distributive-0.6.2.1/docs/Data-Distributive.html#t:Distributive From x at tomsmeding.com Sat Jan 9 09:21:29 2021 From: x at tomsmeding.com (Tom Smeding) Date: Sat, 09 Jan 2021 09:21:29 +0000 Subject: [Haskell-cafe] A quick question about distribution of finite maps. In-Reply-To: References: Message-ID: Hi Ignat, A ghci session: Prelude> import Test.QuickCheck Prelude Test.QuickCheck> import qualified Data.Map.Strict as Map Prelude Test.QuickCheck Map> import Data.Map.Strict (Map) Prelude Test.QuickCheck Map Data.Map.Strict> let distribute = Map.unionsWith Map.union . Map.mapWithKey (fmap . Map.singleton) Prelude Test.QuickCheck Map Data.Map.Strict> quickCheck $ \m -> distribute (distribute m) == (m :: Map Int (Map Int Int)) *** Failed! Falsified (after 2 tests and 2 shrinks): fromList [(0,fromList [])] Prelude Test.QuickCheck Map Data.Map.Strict> distribute (Map.singleton 1 mempty) fromList [] It seems your property fails with the map `fromList [(0, fromList [])]`. I'm not sure if you need it to work for that case; I'm not a category theorist. Cheers, Tom ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ On Saturday, January 9, 2021 9:38 AM, Ignat Insarov wrote: > Hello! > > Finite maps from `"containers" Data.Map` look like they may form a > Cartesian closed category. So it makes sense to ask if the rule α ⇸ > (β ⇸ γ) ≡ ⟨α; β⟩ ⇸ γ ≡ ⟨β; α⟩ ⇸ γ ≡ β ⇸ (α ⇸ γ) that holds in suchcategories does hold for finite maps. Note that, a map being a > functor, this also may be seen as f (g α) ≡ g (f α), which would > work if maps were `Distributive` [1]. > > It looks to me as though the following definition might work: > > distribute = unionsWith union . mapWithKey (fmap . singleton) > > — And it works on simple examples. (I checked the law `distribute ∘ distribute ≡ id` — it appears to be the only law required.) > > Is this definition correct? Is it already known and defined elsewhere? > > [1]: https://hackage.haskell.org/package/distributive-0.6.2.1/docs/Data-Distributive.html#t:Distributive > > 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 seanmatthews1 at gmail.com Sat Jan 9 11:02:46 2021 From: seanmatthews1 at gmail.com (Sean Matthews) Date: Sat, 9 Jan 2021 12:02:46 +0100 Subject: [Haskell-cafe] GHC / macports / Big Sur Message-ID: It may be that someone has already asked this question, but I am having a problem (= it does not work) installing GHC using macports. Pure vanilla Mac/macports, with a few standard installed packages, but deliberately as few manual interventions as possible. Does the group have any advice? Thanks, Sean Matthews PS this is what macports says: r.packages.macports.org/stack ---> Attempting to fetch stack-2.5.1_0.darwin_20.x86_64.tbz2 from https://cph.dk.packages.macports.org/stack ---> Building stack Error: Failed to build stack: command execution failed Error: See /opt/local/var/macports/logs/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_lang_stack/stack/main.log for details. Error: Follow https://guide.macports.org/#project.tickets to report a bug. Error: Processing of port ghc failed ---> Some of the ports you installed have notes: pinentry-mac has the following notes: If you previously didn't have pinentry or gpg-agent installed and pinentry-mac has been installed as a dependency of gpg-agent, you don't need to do anything to use pinentry-mac. If you want to switch to the GTK2, ncurses or Qt4 based pinentry program, please install pinentry with the correct use flags and follow the instructions below substituting the pinentry-mac program path with /opt/local/bin/pinentry. If you previously had pinentry and gpg-agent installed and would like to switch to pinentry-mac, you will have to set it as your pinentry program in $HOME/.gnupg/gpg-agent.conf. Add the following line to the mentioned file: pinentry-program /Applications/MacPorts/pinentry-mac.app/Contents/MacOS/pinentry-mac Be sure to comment previous "pinentry-program" lines, for example: pinentry-program SAMPLE becomes #pinentry-program SAMPLE Afterwards, run killall -HUP gpg-agent or simply log out and back in again. -- Sean Matthews seanmatthews1 at gmail.com / +49 163 803 1396 -------------- next part -------------- An HTML attachment was scrubbed... URL: From kindaro at gmail.com Sat Jan 9 11:30:08 2021 From: kindaro at gmail.com (Ignat Insarov) Date: Sat, 9 Jan 2021 16:30:08 +0500 Subject: [Haskell-cafe] A quick question about distribution of finite maps. In-Reply-To: References: Message-ID: Thanks Tom! This is not a complete disaster theoretically, because a `mempty` map corresponds to a function with `Void` domain which may not be invoked anyway. But truly it makes the definition problematic, in the way similar to how `Set` is not quite a functor — usually it works but sometimes _map g ∘ map f_ may lose more elements than _map (g ∘ f)_. I am not sure how much of sad I should be about it. The function still works most of the time. From x at tomsmeding.com Sat Jan 9 11:33:51 2021 From: x at tomsmeding.com (Tom Smeding) Date: Sat, 09 Jan 2021 11:33:51 +0000 Subject: [Haskell-cafe] GHC / macports / Big Sur In-Reply-To: References: Message-ID: <5Mq7HMqILY6zDPQDiQ5BNTTE_kjRvvBlWy5mdL5EnhFuOVMciVf7pVUW-qQzZ-4HJG0mXfn9z6Yr_YNBXBt8qMN5rWucWdTydjAh0dqqwYc=@tomsmeding.com> Dear Sean, The mentioned log file (/opt/local/var/macports/logs/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_lang_stack/stack/main.log) may contain useful information in debugging the problem, I imagine. Cheers, Tom ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ On Saturday, January 9, 2021 12:02 PM, Sean Matthews wrote: > It may be that someone has already asked this question, but I am having a problem (= it does not work) installing GHC using macports. > Pure vanilla Mac/macports, with a few standard installed packages, but deliberately as few manual interventions as possible. > > Does the group have any advice? > > Thanks, > > Sean Matthews > > PS this is what macports says: > > r.packages.macports.org/stack > > ---> Attempting to fetch stack-2.5.1_0.darwin_20.x86_64.tbz2 from https://cph.dk.packages.macports.org/stack > > ---> Building stack > > Error: Failed to build stack: command execution failed > > Error: See /opt/local/var/macports/logs/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_lang_stack/stack/main.log for details. > > Error: Follow https://guide.macports.org/#project.tickets to report a bug. > > Error: Processing of port ghc failed > > ---> Some of the ports you installed have notes: > > pinentry-mac has the following notes: > > If you previously didn't have pinentry or gpg-agent installed and > > pinentry-mac has been installed as a dependency of gpg-agent, you don't > > need to do anything to use pinentry-mac. > > If you want to switch to the GTK2, ncurses or Qt4 based pinentry program, > > please install pinentry with the correct use flags and follow the > > instructions below substituting the pinentry-mac program path with > > /opt/local/bin/pinentry. > > If you previously had pinentry and gpg-agent installed and would like to > > switch to pinentry-mac, you will have to set it as your pinentry program in > > $HOME/.gnupg/gpg-agent.conf. > > Add the following line to the mentioned file: > > pinentry-program > > /Applications/MacPorts/pinentry-mac.app/Contents/MacOS/pinentry-mac > > Be sure to comment previous "pinentry-program" lines, for example: > > pinentry-program SAMPLE > > becomes > > #pinentry-program SAMPLE > > Afterwards, run > > killall -HUP gpg-agent > > or simply log out and back in again. > > -- > Sean Matthews > seanmatthews1 at gmail.com / +49 163 803 1396 -------------- next part -------------- An HTML attachment was scrubbed... URL: From tonyzorman at mailbox.org Sat Jan 9 12:12:02 2021 From: tonyzorman at mailbox.org (Tony Zorman) Date: Sat, 09 Jan 2021 13:12:02 +0100 Subject: [Haskell-cafe] A quick question about distribution of finite maps. In-Reply-To: References: Message-ID: <87v9c6b97x.fsf@hyperspace> On Sat, Jan 09 2021 16:30, Ignat Insarov wrote: > This is not a complete disaster theoretically, because a `mempty` map > corresponds to a function with `Void` domain which may not be invoked > anyway.  A law failing just because the object one is looking at happens to be inital sounds like a pretty severe theoretical disaster to me. > Finite maps from `"containers" Data.Map` look like they may form a > Cartesian closed category. What category are you using as a base here? I suppose it's not just Set, as one could easily model finite maps as a finite set of tuples there (and finite sets are definitely cartesian closed); is it some idealised version of Hask (so that it actually exists :-)? From kindaro at gmail.com Sat Jan 9 13:57:29 2021 From: kindaro at gmail.com (Ignat Insarov) Date: Sat, 9 Jan 2021 18:57:29 +0500 Subject: [Haskell-cafe] A quick question about distribution of finite maps. In-Reply-To: <87v9c6b97x.fsf@hyperspace> References: <87v9c6b97x.fsf@hyperspace> Message-ID: > > This is not a complete disaster theoretically, because a `mempty` map > > corresponds to a function with `Void` domain which may not be invoked > > anyway. > > A law failing just because the object one is looking at happens to be inital > sounds like a pretty severe theoretical disaster to me. When I said _«theoretically»_, I meant that a map `Map.singleton 1 (mempty :: Map)` is the same as `mempty :: Map` because there is no such tuple of keys that you would be able to extract any value. In other words, _{1} × { } ⇸ α_ is the same as _{ } ⇸ α_, so both are of type `Void → α` and there is only one such map. Insofar as I only care about values, I may never observe a difference. By the way, finite maps are also problematic in the sense that there is any number of identity maps of the same type, one for each finite subset of that type. This makes it impossible to define a category of finite maps formally within the Haskell type system. So maybe I should speak instead of a semigroupoid and a semigroup of finite maps, removing both these corner cases from consideration. The reality is that empty maps are my enemy anyway — I even have a special function: dropEmpty :: (Filterable g, Foldable f) => g (f a) -> g (f a) dropEmpty = Witherable.filter (not . null) — To contain their proliferation. Of course, there are many ways an empty map may appear, such as via intersection of maps with disjoint source sets. So some usual operations would need to acquire more complicated types. > What category are you using as a base here? I suppose it's not just Set, as > one could easily model finite maps as a finite set of tuples there (and finite > sets are definitely cartesian closed); is it some idealised version of Hask > (so that it actually exists :-)? I am not sure I follow you here. I see how we may model relations as sets of tuples, but finite maps definitely need to be an abstract type of its own to ensure that they are actually _functional_relations. The category **Haskell** of Haskell types and total functions is not a suitable category for these entities, because you cannot represent subsets in it, and subsets are kinda the whole point of the exercise. So I look at it as though **Haskell** is a subcategory of **Set** and **Finite Set** — the category of finite sets and finite maps — is another, although not entirely disjoint subcategory. From viercc at gmail.com Sat Jan 9 16:42:09 2021 From: viercc at gmail.com (=?UTF-8?B?5a6u6YeM5rS45Y+4?=) Date: Sun, 10 Jan 2021 01:42:09 +0900 Subject: [Haskell-cafe] A quick question about distribution of finite maps. In-Reply-To: References: <87v9c6b97x.fsf@hyperspace> Message-ID: Hi Ignat, would you slow down a bit and tell us the idea behind your question? You seem to expect Map forms a Cartesian closed category, and want to know if the specific property of CCC holds ("functors of shape (a ⇸ -) are distributive".) Could you explain that expectation step-by-step? For the first step, let us know the category made from Maps more clearly. I mean, (1) what are the objects of that category? (2) what are the morphisms? (3) how the identity morphisms and the composition of morphisms are defined? The next step would be the "Cartesian" part. This category should have direct product of any finite number of objects. What exactly are these, and how do you define the projection morphisms (equivalents of `fst` and `snd` in your category) and the product of morphisms (equivalent of `&&&`.) It's too rushed to think about CCC until these aren't clear. -- /* Koji Miyazato */ From olf at aatal-apotheke.de Sat Jan 9 21:01:15 2021 From: olf at aatal-apotheke.de (Olaf Klinke) Date: Sat, 09 Jan 2021 22:01:15 +0100 Subject: [Haskell-cafe] A quick question about distribution of finite maps. Message-ID: > Hello! > > Finite maps from `"containers" Data.Map` look like they may form a > Cartesian closed category. So it makes sense to ask if the rule _α ⇸ > (β ⇸ γ) ≡ ⟨α; β⟩ ⇸ γ ≡ ⟨β; α⟩ ⇸ γ ≡ β ⇸ (α ⇸ γ)_ that holds in such > categories does hold for finite maps. Note that, a map being a > functor, this also may be seen as _f (g α) ≡ g (f α)_, which would > work if maps were `Distributive` [1]. > > It looks to me as though the following definition might work: > > distribute = unionsWith union . mapWithKey (fmap . singleton) > > — And it works on simple examples. _(I checked the law `distribute ∘ > distribute ≡ id` — it appears to be the only law required.)_ > > Is this definition correct? Is it already known and defined > elsewhere? > > [1]: > https://hackage.haskell.org/package/distributive-0.6.2.1/docs/Data-Distributive.html#t:Distributive Hi Ignat, TL;DR: No and no. The documentation says that every distributive functor is of the form (->) x for some x, and (Map a) is not like this. If Maps were a category, what is the identity morphism? Let's put the Ord constraint on the keys aside, Tom Smeding has already commented on that. Next, a Map is always finite, hence let's pretend that we are working inside the category of finite types and functions. Then the problems of missing identity and missing Ord go away. Once that all types are finite, we can assume an enumerator. That is, each type x has an operation enumerate :: [x] which we will use to construct the inverse of flip Map.lookup :: Map a b -> a -> Maybe b thereby showing that a Map is nothing but a memoized version of a Kleisli map (a -> Maybe b). Convince yourself that Map concatenation has the same semantics as Kleisli composition (<=<). Given a Kleisli map k between finite types, we build a Map as follows. \k -> Map.fromList (enumerate >>= (\a -> maybe [] (pure.(,) a) (k a))) With that knowledge, we can answer your question by deciding: Is the Kleisli category of the Maybe monad on finite types Cartesian closed? Short answer: It is not even Cartesian. There is an adjunction between the categories (->) and (Kleisli m) for every monad m, where * The left adjoint functor takes types x to x, functions f to return.f * The right adjoint functor takes types x to m x, Kleisli maps f to (=<<) f Right adjoint functors preserve all existing limits, which includes products. Therefore, if (Kleisli m) has binary products, then m must preserve them. So if P x y was the product of x and y in Kleisli m, then m (P x y) would be isomorphic to (m x,m y). This seems not to hold for m = Maybe: I can not imagine a type constructor P where Maybe (P x y) ~ (Maybe x,Maybe y). In particular, P can not be (,). The only sensible Kleisli projections from (x,y) would be fst' = return.fst and snd' = return.snd. Now think of two Kleisli maps f :: Bool -> Maybe x, g :: Bool -> Maybe y. Assume that f True = Just x for some x and g True = Nothing. In order to satisfy g True = (snd' <=< (f&&&g))True, the unique pair arrow (f&&&g) would need to map True to Nothing, but then f True = (fst' <=< (f&&&g)) True can not hold. We conclude that (Kleisli Maybe) does not even have categorical products, so asking for Cartesian closure does not make sense. You might ask for a weaker property: For every type x, ((,) x) is a functor on (Kleisli Maybe). Indeed, the following works because ((,) x) is a polynomial functor. fmapKleisli :: Functor m => (a -> m b) -> (x,a) -> m (x,b) fmapKleisli f (x,a) = fmap ((,) x) (f a) Thus you may ask whether this functor has a right adjoint in the Kleisli category of Maybe. This would be a type constructor g with a natural isomorphism (x,a) -> Maybe b ~ a -> Maybe (g b). The first thing that comes to mind is to try g b = x -> Maybe b and indeed djinn can provide two functions going back and forth that have the right type, but they do not establish an isomorphism. I doubt there is such a right adjoint g, but can not prove it at the moment. The idea is that a function (x,a) -> Maybe b may decide for Nothing depending on both x and a, and therefore the image function under the isomorphism must map every a to Just (g b) and delay the Nothing-decision to the g b. But for the reverse isomorphism you can have functions that do not always return Just (g b) and there is no preimage for these. Regards, Olaf From david.feuer at gmail.com Sat Jan 9 21:11:21 2021 From: david.feuer at gmail.com (David Feuer) Date: Sat, 9 Jan 2021 16:11:21 -0500 Subject: [Haskell-cafe] A quick question about distribution of finite maps. In-Reply-To: References: Message-ID: I don't know any of this category theory stuff, but you write "I can not imagine a type constructor P where Maybe (P x y) ~ (Maybe x,Maybe y)". Unless there's some important condition missing from your statement, there indeed is such a constructor: data These a b = This a | That b | These a b Nothing -> (Nothing, Nothing) Just (This a) -> (Just a, Nothing) Just (That b) -> (Nothing, Just b) Just (These a b) -> (Just a, Just b) On Sat, Jan 9, 2021, 4:01 PM Olaf Klinke wrote: > > Hello! > > > > Finite maps from `"containers" Data.Map` look like they may form a > > Cartesian closed category. So it makes sense to ask if the rule _α ⇸ > > (β ⇸ γ) ≡ ⟨α; β⟩ ⇸ γ ≡ ⟨β; α⟩ ⇸ γ ≡ β ⇸ (α ⇸ γ)_ that holds in such > > categories does hold for finite maps. Note that, a map being a > > functor, this also may be seen as _f (g α) ≡ g (f α)_, which would > > work if maps were `Distributive` [1]. > > > > It looks to me as though the following definition might work: > > > > distribute = unionsWith union . mapWithKey (fmap . singleton) > > > > — And it works on simple examples. _(I checked the law `distribute ∘ > > distribute ≡ id` — it appears to be the only law required.)_ > > > > Is this definition correct? Is it already known and defined > > elsewhere? > > > > [1]: > > > https://hackage.haskell.org/package/distributive-0.6.2.1/docs/Data-Distributive.html#t:Distributive > > Hi Ignat, > > TL;DR: No and no. > > The documentation says that every distributive functor is of the form > (->) x for some x, and (Map a) is not like this. > > If Maps were a category, what is the identity morphism? > > Let's put the Ord constraint on the keys aside, Tom Smeding has already > commented on that. Next, a Map is always finite, hence let's pretend > that we are working inside the category of finite types and functions. > Then the problems of missing identity and missing Ord go away. Once > that all types are finite, we can assume an enumerator. That is, each > type x has an operation > enumerate :: [x] > which we will use to construct the inverse of > flip Map.lookup :: Map a b -> a -> Maybe b > thereby showing that a Map is nothing but a memoized version of a > Kleisli map (a -> Maybe b). Convince yourself that Map concatenation > has the same semantics as Kleisli composition (<=<). Given a Kleisli > map k between finite types, we build a Map as follows. > \k -> Map.fromList (enumerate >>= (\a -> maybe [] (pure.(,) a) (k a))) > > With that knowledge, we can answer your question by deciding: Is the > Kleisli category of the Maybe monad on finite types Cartesian closed? > Short answer: It is not even Cartesian. > There is an adjunction between the categories (->) and (Kleisli m) for > every monad m, where > * The left adjoint functor takes > types x to x, > functions f to return.f > * The right adjoint functor takes > types x to m x, > Kleisli maps f to (=<<) f > Right adjoint functors preserve all existing limits, which includes > products. Therefore, if (Kleisli m) has binary products, then m must > preserve them. So if P x y was the product of x and y in Kleisli m, > then m (P x y) would be isomorphic to (m x,m y). This seems not to hold > for m = Maybe: I can not imagine a type constructor P where > Maybe (P x y) ~ (Maybe x,Maybe y). > In particular, P can not be (,). The only sensible Kleisli projections > from (x,y) would be fst' = return.fst and snd' = return.snd. Now think > of two Kleisli maps f :: Bool -> Maybe x, g :: Bool -> Maybe y. Assume > that f True = Just x for some x and g True = Nothing. In order to > satisfy g True = (snd' <=< (f&&&g))True, the unique pair arrow (f&&&g) > would need to map True to Nothing, but then f True = (fst' <=< (f&&&g)) > True can not hold. We conclude that (Kleisli Maybe) does not even have > categorical products, so asking for Cartesian closure does not make > sense. > > You might ask for a weaker property: For every type x, ((,) x) is a > functor on (Kleisli Maybe). Indeed, the following works because ((,) x) > is a polynomial functor. > fmapKleisli :: Functor m => (a -> m b) -> (x,a) -> m (x,b) > fmapKleisli f (x,a) = fmap ((,) x) (f a) > Thus you may ask whether this functor has a right adjoint in the > Kleisli category of Maybe. This would be a type constructor g with a > natural isomorphism > > (x,a) -> Maybe b ~ a -> Maybe (g b). > > The first thing that comes to mind is to try > g b = x -> Maybe b and indeed djinn can provide two functions going > back and forth that have the right type, but they do not establish an > isomorphism. I doubt there is such a right adjoint g, but can not prove > it at the moment. The idea is that a function (x,a) -> Maybe b may > decide for Nothing depending on both x and a, and therefore the image > function under the isomorphism must map every a to Just (g b) and delay > the Nothing-decision to the g b. But for the reverse isomorphism you > can have functions that do not always return Just (g b) and there is no > preimage for these. > > Regards, > Olaf > > > > _______________________________________________ > 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 migmit at gmail.com Sat Jan 9 21:26:28 2021 From: migmit at gmail.com (MigMit) Date: Sat, 9 Jan 2021 22:26:28 +0100 Subject: [Haskell-cafe] A quick question about distribution of finite maps. In-Reply-To: References: Message-ID: Actually, it's pretty easy to construct a type `P x y`, so that Maybe (P x y) ~ (Maybe x, Maybe y). It would be data OneOrBoth x y = Left' x | Right' y | Both x y The isomorphism is, I think, obvious iso1 :: Maybe (OneOrBoth x y) -> (Maybe x, Maybe y) iso1 Nothing = (Nothing, Nothing) iso1 (Just (Left' x)) = (Just x, Nothing) iso1 (Just (Right' y)) = (Nothing, Just y) iso1 (Just (Both x y)) = (Just x, Just y) iso2 :: (Maybe x, Maybe y) -> Maybe (OneOrBoth x y) iso2 = -- left as an excersize for the reader And indeed, "OneOrBoth" would be a cartesian product functor in the category of finite types (and maps). But it won't be cartesian closed. If it were, then for any finite X and Y we should have Maybe (X^Y) ~ () -> Maybe (X^Y) ~ OneOrBoth () Y -> Maybe X ~ (() -> Maybe X, Y -> Maybe X, ((), Y) -> Maybe X) ~ (Maybe X, Y -> Maybe X, Y -> Maybe X) so X^Y ~ (X, Y -> Maybe X, Y -> Maybe X) But then Z -> Maybe (X^Y) ~ Z -> (Maybe X, Y -> Maybe X, Y -> Maybe X) ~ (Z -> Maybe X, (Z, Y) -> Maybe X, (Z, Y) -> Maybe X) ~ and OneOrBoth Z Y -> Maybe X ~ (Z -> Maybe X, Y -> Maybe X, (Z, Y) -> Maybe X) We see that those aren't the same, they have a different number of elements, so, no luck. > On 9 Jan 2021, at 22:01, Olaf Klinke wrote: > >> Hello! >> >> Finite maps from `"containers" Data.Map` look like they may form a >> Cartesian closed category. So it makes sense to ask if the rule _α ⇸ >> (β ⇸ γ) ≡ ⟨α; β⟩ ⇸ γ ≡ ⟨β; α⟩ ⇸ γ ≡ β ⇸ (α ⇸ γ)_ that holds in such >> categories does hold for finite maps. Note that, a map being a >> functor, this also may be seen as _f (g α) ≡ g (f α)_, which would >> work if maps were `Distributive` [1]. >> >> It looks to me as though the following definition might work: >> >> distribute = unionsWith union . mapWithKey (fmap . singleton) >> >> — And it works on simple examples. _(I checked the law `distribute ∘ >> distribute ≡ id` — it appears to be the only law required.)_ >> >> Is this definition correct? Is it already known and defined >> elsewhere? >> >> [1]: >> https://hackage.haskell.org/package/distributive-0.6.2.1/docs/Data-Distributive.html#t:Distributive > > Hi Ignat, > > TL;DR: No and no. > > The documentation says that every distributive functor is of the form > (->) x for some x, and (Map a) is not like this. > > If Maps were a category, what is the identity morphism? > > Let's put the Ord constraint on the keys aside, Tom Smeding has already > commented on that. Next, a Map is always finite, hence let's pretend > that we are working inside the category of finite types and functions. > Then the problems of missing identity and missing Ord go away. Once > that all types are finite, we can assume an enumerator. That is, each > type x has an operation > enumerate :: [x] > which we will use to construct the inverse of > flip Map.lookup :: Map a b -> a -> Maybe b > thereby showing that a Map is nothing but a memoized version of a > Kleisli map (a -> Maybe b). Convince yourself that Map concatenation > has the same semantics as Kleisli composition (<=<). Given a Kleisli > map k between finite types, we build a Map as follows. > \k -> Map.fromList (enumerate >>= (\a -> maybe [] (pure.(,) a) (k a))) > > With that knowledge, we can answer your question by deciding: Is the > Kleisli category of the Maybe monad on finite types Cartesian closed? > Short answer: It is not even Cartesian. > There is an adjunction between the categories (->) and (Kleisli m) for > every monad m, where > * The left adjoint functor takes > types x to x, > functions f to return.f > * The right adjoint functor takes > types x to m x, > Kleisli maps f to (=<<) f > Right adjoint functors preserve all existing limits, which includes > products. Therefore, if (Kleisli m) has binary products, then m must > preserve them. So if P x y was the product of x and y in Kleisli m, > then m (P x y) would be isomorphic to (m x,m y). This seems not to hold > for m = Maybe: I can not imagine a type constructor P where > Maybe (P x y) ~ (Maybe x,Maybe y). > In particular, P can not be (,). The only sensible Kleisli projections > from (x,y) would be fst' = return.fst and snd' = return.snd. Now think > of two Kleisli maps f :: Bool -> Maybe x, g :: Bool -> Maybe y. Assume > that f True = Just x for some x and g True = Nothing. In order to > satisfy g True = (snd' <=< (f&&&g))True, the unique pair arrow (f&&&g) > would need to map True to Nothing, but then f True = (fst' <=< (f&&&g)) > True can not hold. We conclude that (Kleisli Maybe) does not even have > categorical products, so asking for Cartesian closure does not make > sense. > > You might ask for a weaker property: For every type x, ((,) x) is a > functor on (Kleisli Maybe). Indeed, the following works because ((,) x) > is a polynomial functor. > fmapKleisli :: Functor m => (a -> m b) -> (x,a) -> m (x,b) > fmapKleisli f (x,a) = fmap ((,) x) (f a) > Thus you may ask whether this functor has a right adjoint in the > Kleisli category of Maybe. This would be a type constructor g with a > natural isomorphism > > (x,a) -> Maybe b ~ a -> Maybe (g b). > > The first thing that comes to mind is to try > g b = x -> Maybe b and indeed djinn can provide two functions going > back and forth that have the right type, but they do not establish an > isomorphism. I doubt there is such a right adjoint g, but can not prove > it at the moment. The idea is that a function (x,a) -> Maybe b may > decide for Nothing depending on both x and a, and therefore the image > function under the isomorphism must map every a to Just (g b) and delay > the Nothing-decision to the g b. But for the reverse isomorphism you > can have functions that do not always return Just (g b) and there is no > preimage for these. > > Regards, > Olaf > > > > _______________________________________________ > 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 david.feuer at gmail.com Sat Jan 9 21:37:38 2021 From: david.feuer at gmail.com (David Feuer) Date: Sat, 9 Jan 2021 16:37:38 -0500 Subject: [Haskell-cafe] A quick question about distribution of finite maps. In-Reply-To: References: Message-ID: Where do you get () -> Maybe (X^Y) ~ OneOrBoth () Y -> Maybe X On Sat, Jan 9, 2021, 4:26 PM MigMit wrote: > Actually, it's pretty easy to construct a type `P x y`, so that Maybe (P x > y) ~ (Maybe x, Maybe y). It would be > > data OneOrBoth x y = Left' x | Right' y | Both x y > > The isomorphism is, I think, obvious > > iso1 :: Maybe (OneOrBoth x y) -> (Maybe x, Maybe y) > iso1 Nothing = (Nothing, Nothing) > iso1 (Just (Left' x)) = (Just x, Nothing) > iso1 (Just (Right' y)) = (Nothing, Just y) > iso1 (Just (Both x y)) = (Just x, Just y) > > iso2 :: (Maybe x, Maybe y) -> Maybe (OneOrBoth x y) > iso2 = -- left as an excersize for the reader > > And indeed, "OneOrBoth" would be a cartesian product functor in the > category of finite types (and maps). > > But it won't be cartesian closed. If it were, then for any finite X and Y > we should have > > Maybe (X^Y) ~ > () -> Maybe (X^Y) ~ > OneOrBoth () Y -> Maybe X ~ > (() -> Maybe X, Y -> Maybe X, ((), Y) -> Maybe X) ~ > (Maybe X, Y -> Maybe X, Y -> Maybe X) > > so > > X^Y ~ (X, Y -> Maybe X, Y -> Maybe X) > > But then > > Z -> Maybe (X^Y) ~ > Z -> (Maybe X, Y -> Maybe X, Y -> Maybe X) ~ > (Z -> Maybe X, (Z, Y) -> Maybe X, (Z, Y) -> Maybe X) ~ > > and > > OneOrBoth Z Y -> Maybe X ~ > (Z -> Maybe X, Y -> Maybe X, (Z, Y) -> Maybe X) > > We see that those aren't the same, they have a different number of > elements, so, no luck. > > > On 9 Jan 2021, at 22:01, Olaf Klinke wrote: > > > >> Hello! > >> > >> Finite maps from `"containers" Data.Map` look like they may form a > >> Cartesian closed category. So it makes sense to ask if the rule _α ⇸ > >> (β ⇸ γ) ≡ ⟨α; β⟩ ⇸ γ ≡ ⟨β; α⟩ ⇸ γ ≡ β ⇸ (α ⇸ γ)_ that holds in such > >> categories does hold for finite maps. Note that, a map being a > >> functor, this also may be seen as _f (g α) ≡ g (f α)_, which would > >> work if maps were `Distributive` [1]. > >> > >> It looks to me as though the following definition might work: > >> > >> distribute = unionsWith union . mapWithKey (fmap . singleton) > >> > >> — And it works on simple examples. _(I checked the law `distribute ∘ > >> distribute ≡ id` — it appears to be the only law required.)_ > >> > >> Is this definition correct? Is it already known and defined > >> elsewhere? > >> > >> [1]: > >> > https://hackage.haskell.org/package/distributive-0.6.2.1/docs/Data-Distributive.html#t:Distributive > > > > Hi Ignat, > > > > TL;DR: No and no. > > > > The documentation says that every distributive functor is of the form > > (->) x for some x, and (Map a) is not like this. > > > > If Maps were a category, what is the identity morphism? > > > > Let's put the Ord constraint on the keys aside, Tom Smeding has already > > commented on that. Next, a Map is always finite, hence let's pretend > > that we are working inside the category of finite types and functions. > > Then the problems of missing identity and missing Ord go away. Once > > that all types are finite, we can assume an enumerator. That is, each > > type x has an operation > > enumerate :: [x] > > which we will use to construct the inverse of > > flip Map.lookup :: Map a b -> a -> Maybe b > > thereby showing that a Map is nothing but a memoized version of a > > Kleisli map (a -> Maybe b). Convince yourself that Map concatenation > > has the same semantics as Kleisli composition (<=<). Given a Kleisli > > map k between finite types, we build a Map as follows. > > \k -> Map.fromList (enumerate >>= (\a -> maybe [] (pure.(,) a) (k a))) > > > > With that knowledge, we can answer your question by deciding: Is the > > Kleisli category of the Maybe monad on finite types Cartesian closed? > > Short answer: It is not even Cartesian. > > There is an adjunction between the categories (->) and (Kleisli m) for > > every monad m, where > > * The left adjoint functor takes > > types x to x, > > functions f to return.f > > * The right adjoint functor takes > > types x to m x, > > Kleisli maps f to (=<<) f > > Right adjoint functors preserve all existing limits, which includes > > products. Therefore, if (Kleisli m) has binary products, then m must > > preserve them. So if P x y was the product of x and y in Kleisli m, > > then m (P x y) would be isomorphic to (m x,m y). This seems not to hold > > for m = Maybe: I can not imagine a type constructor P where > > Maybe (P x y) ~ (Maybe x,Maybe y). > > In particular, P can not be (,). The only sensible Kleisli projections > > from (x,y) would be fst' = return.fst and snd' = return.snd. Now think > > of two Kleisli maps f :: Bool -> Maybe x, g :: Bool -> Maybe y. Assume > > that f True = Just x for some x and g True = Nothing. In order to > > satisfy g True = (snd' <=< (f&&&g))True, the unique pair arrow (f&&&g) > > would need to map True to Nothing, but then f True = (fst' <=< (f&&&g)) > > True can not hold. We conclude that (Kleisli Maybe) does not even have > > categorical products, so asking for Cartesian closure does not make > > sense. > > > > You might ask for a weaker property: For every type x, ((,) x) is a > > functor on (Kleisli Maybe). Indeed, the following works because ((,) x) > > is a polynomial functor. > > fmapKleisli :: Functor m => (a -> m b) -> (x,a) -> m (x,b) > > fmapKleisli f (x,a) = fmap ((,) x) (f a) > > Thus you may ask whether this functor has a right adjoint in the > > Kleisli category of Maybe. This would be a type constructor g with a > > natural isomorphism > > > > (x,a) -> Maybe b ~ a -> Maybe (g b). > > > > The first thing that comes to mind is to try > > g b = x -> Maybe b and indeed djinn can provide two functions going > > back and forth that have the right type, but they do not establish an > > isomorphism. I doubt there is such a right adjoint g, but can not prove > > it at the moment. The idea is that a function (x,a) -> Maybe b may > > decide for Nothing depending on both x and a, and therefore the image > > function under the isomorphism must map every a to Just (g b) and delay > > the Nothing-decision to the g b. But for the reverse isomorphism you > > can have functions that do not always return Just (g b) and there is no > > preimage for these. > > > > Regards, > > Olaf > > > > > > > > _______________________________________________ > > 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 migmit at gmail.com Sat Jan 9 21:41:25 2021 From: migmit at gmail.com (MigMit) Date: Sat, 9 Jan 2021 22:41:25 +0100 Subject: [Haskell-cafe] A quick question about distribution of finite maps. In-Reply-To: References: Message-ID: From the definition. To have a cartesian closed category you need some X^Y such that Z => X^Y ~ ZxY => X If your (=>) is defined as A => B ~ A -> Maybe B, and your AxB is OneOrBoth A B, then that's what you get. > On 9 Jan 2021, at 22:37, David Feuer wrote: > > Where do you get > > () -> Maybe (X^Y) ~ > OneOrBoth () Y -> Maybe X > > On Sat, Jan 9, 2021, 4:26 PM MigMit wrote: > Actually, it's pretty easy to construct a type `P x y`, so that Maybe (P x y) ~ (Maybe x, Maybe y). It would be > > data OneOrBoth x y = Left' x | Right' y | Both x y > > The isomorphism is, I think, obvious > > iso1 :: Maybe (OneOrBoth x y) -> (Maybe x, Maybe y) > iso1 Nothing = (Nothing, Nothing) > iso1 (Just (Left' x)) = (Just x, Nothing) > iso1 (Just (Right' y)) = (Nothing, Just y) > iso1 (Just (Both x y)) = (Just x, Just y) > > iso2 :: (Maybe x, Maybe y) -> Maybe (OneOrBoth x y) > iso2 = -- left as an excersize for the reader > > And indeed, "OneOrBoth" would be a cartesian product functor in the category of finite types (and maps). > > But it won't be cartesian closed. If it were, then for any finite X and Y we should have > > Maybe (X^Y) ~ > () -> Maybe (X^Y) ~ > OneOrBoth () Y -> Maybe X ~ > (() -> Maybe X, Y -> Maybe X, ((), Y) -> Maybe X) ~ > (Maybe X, Y -> Maybe X, Y -> Maybe X) > > so > > X^Y ~ (X, Y -> Maybe X, Y -> Maybe X) > > But then > > Z -> Maybe (X^Y) ~ > Z -> (Maybe X, Y -> Maybe X, Y -> Maybe X) ~ > (Z -> Maybe X, (Z, Y) -> Maybe X, (Z, Y) -> Maybe X) ~ > > and > > OneOrBoth Z Y -> Maybe X ~ > (Z -> Maybe X, Y -> Maybe X, (Z, Y) -> Maybe X) > > We see that those aren't the same, they have a different number of elements, so, no luck. > > > On 9 Jan 2021, at 22:01, Olaf Klinke wrote: > > > >> Hello! > >> > >> Finite maps from `"containers" Data.Map` look like they may form a > >> Cartesian closed category. So it makes sense to ask if the rule _α ⇸ > >> (β ⇸ γ) ≡ ⟨α; β⟩ ⇸ γ ≡ ⟨β; α⟩ ⇸ γ ≡ β ⇸ (α ⇸ γ)_ that holds in such > >> categories does hold for finite maps. Note that, a map being a > >> functor, this also may be seen as _f (g α) ≡ g (f α)_, which would > >> work if maps were `Distributive` [1]. > >> > >> It looks to me as though the following definition might work: > >> > >> distribute = unionsWith union . mapWithKey (fmap . singleton) > >> > >> — And it works on simple examples. _(I checked the law `distribute ∘ > >> distribute ≡ id` — it appears to be the only law required.)_ > >> > >> Is this definition correct? Is it already known and defined > >> elsewhere? > >> > >> [1]: > >> https://hackage.haskell.org/package/distributive-0.6.2.1/docs/Data-Distributive.html#t:Distributive > > > > Hi Ignat, > > > > TL;DR: No and no. > > > > The documentation says that every distributive functor is of the form > > (->) x for some x, and (Map a) is not like this. > > > > If Maps were a category, what is the identity morphism? > > > > Let's put the Ord constraint on the keys aside, Tom Smeding has already > > commented on that. Next, a Map is always finite, hence let's pretend > > that we are working inside the category of finite types and functions. > > Then the problems of missing identity and missing Ord go away. Once > > that all types are finite, we can assume an enumerator. That is, each > > type x has an operation > > enumerate :: [x] > > which we will use to construct the inverse of > > flip Map.lookup :: Map a b -> a -> Maybe b > > thereby showing that a Map is nothing but a memoized version of a > > Kleisli map (a -> Maybe b). Convince yourself that Map concatenation > > has the same semantics as Kleisli composition (<=<). Given a Kleisli > > map k between finite types, we build a Map as follows. > > \k -> Map.fromList (enumerate >>= (\a -> maybe [] (pure.(,) a) (k a))) > > > > With that knowledge, we can answer your question by deciding: Is the > > Kleisli category of the Maybe monad on finite types Cartesian closed? > > Short answer: It is not even Cartesian. > > There is an adjunction between the categories (->) and (Kleisli m) for > > every monad m, where > > * The left adjoint functor takes > > types x to x, > > functions f to return.f > > * The right adjoint functor takes > > types x to m x, > > Kleisli maps f to (=<<) f > > Right adjoint functors preserve all existing limits, which includes > > products. Therefore, if (Kleisli m) has binary products, then m must > > preserve them. So if P x y was the product of x and y in Kleisli m, > > then m (P x y) would be isomorphic to (m x,m y). This seems not to hold > > for m = Maybe: I can not imagine a type constructor P where > > Maybe (P x y) ~ (Maybe x,Maybe y). > > In particular, P can not be (,). The only sensible Kleisli projections > > from (x,y) would be fst' = return.fst and snd' = return.snd. Now think > > of two Kleisli maps f :: Bool -> Maybe x, g :: Bool -> Maybe y. Assume > > that f True = Just x for some x and g True = Nothing. In order to > > satisfy g True = (snd' <=< (f&&&g))True, the unique pair arrow (f&&&g) > > would need to map True to Nothing, but then f True = (fst' <=< (f&&&g)) > > True can not hold. We conclude that (Kleisli Maybe) does not even have > > categorical products, so asking for Cartesian closure does not make > > sense. > > > > You might ask for a weaker property: For every type x, ((,) x) is a > > functor on (Kleisli Maybe). Indeed, the following works because ((,) x) > > is a polynomial functor. > > fmapKleisli :: Functor m => (a -> m b) -> (x,a) -> m (x,b) > > fmapKleisli f (x,a) = fmap ((,) x) (f a) > > Thus you may ask whether this functor has a right adjoint in the > > Kleisli category of Maybe. This would be a type constructor g with a > > natural isomorphism > > > > (x,a) -> Maybe b ~ a -> Maybe (g b). > > > > The first thing that comes to mind is to try > > g b = x -> Maybe b and indeed djinn can provide two functions going > > back and forth that have the right type, but they do not establish an > > isomorphism. I doubt there is such a right adjoint g, but can not prove > > it at the moment. The idea is that a function (x,a) -> Maybe b may > > decide for Nothing depending on both x and a, and therefore the image > > function under the isomorphism must map every a to Just (g b) and delay > > the Nothing-decision to the g b. But for the reverse isomorphism you > > can have functions that do not always return Just (g b) and there is no > > preimage for these. > > > > Regards, > > Olaf > > > > > > > > _______________________________________________ > > 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 david.feuer at gmail.com Sat Jan 9 21:42:26 2021 From: david.feuer at gmail.com (David Feuer) Date: Sat, 9 Jan 2021 16:42:26 -0500 Subject: [Haskell-cafe] A quick question about distribution of finite maps. In-Reply-To: References: Message-ID: Ah, I see. On Sat, Jan 9, 2021, 4:41 PM MigMit wrote: > From the definition. To have a cartesian closed category you need some X^Y > such that > > Z => X^Y ~ ZxY => X > > If your (=>) is defined as A => B ~ A -> Maybe B, and your AxB is > OneOrBoth A B, then that's what you get. > > > On 9 Jan 2021, at 22:37, David Feuer wrote: > > > > Where do you get > > > > () -> Maybe (X^Y) ~ > > OneOrBoth () Y -> Maybe X > > > > On Sat, Jan 9, 2021, 4:26 PM MigMit wrote: > > Actually, it's pretty easy to construct a type `P x y`, so that Maybe (P > x y) ~ (Maybe x, Maybe y). It would be > > > > data OneOrBoth x y = Left' x | Right' y | Both x y > > > > The isomorphism is, I think, obvious > > > > iso1 :: Maybe (OneOrBoth x y) -> (Maybe x, Maybe y) > > iso1 Nothing = (Nothing, Nothing) > > iso1 (Just (Left' x)) = (Just x, Nothing) > > iso1 (Just (Right' y)) = (Nothing, Just y) > > iso1 (Just (Both x y)) = (Just x, Just y) > > > > iso2 :: (Maybe x, Maybe y) -> Maybe (OneOrBoth x y) > > iso2 = -- left as an excersize for the reader > > > > And indeed, "OneOrBoth" would be a cartesian product functor in the > category of finite types (and maps). > > > > But it won't be cartesian closed. If it were, then for any finite X and > Y we should have > > > > Maybe (X^Y) ~ > > () -> Maybe (X^Y) ~ > > OneOrBoth () Y -> Maybe X ~ > > (() -> Maybe X, Y -> Maybe X, ((), Y) -> Maybe X) ~ > > (Maybe X, Y -> Maybe X, Y -> Maybe X) > > > > so > > > > X^Y ~ (X, Y -> Maybe X, Y -> Maybe X) > > > > But then > > > > Z -> Maybe (X^Y) ~ > > Z -> (Maybe X, Y -> Maybe X, Y -> Maybe X) ~ > > (Z -> Maybe X, (Z, Y) -> Maybe X, (Z, Y) -> Maybe X) ~ > > > > and > > > > OneOrBoth Z Y -> Maybe X ~ > > (Z -> Maybe X, Y -> Maybe X, (Z, Y) -> Maybe X) > > > > We see that those aren't the same, they have a different number of > elements, so, no luck. > > > > > On 9 Jan 2021, at 22:01, Olaf Klinke wrote: > > > > > >> Hello! > > >> > > >> Finite maps from `"containers" Data.Map` look like they may form a > > >> Cartesian closed category. So it makes sense to ask if the rule _α ⇸ > > >> (β ⇸ γ) ≡ ⟨α; β⟩ ⇸ γ ≡ ⟨β; α⟩ ⇸ γ ≡ β ⇸ (α ⇸ γ)_ that holds in such > > >> categories does hold for finite maps. Note that, a map being a > > >> functor, this also may be seen as _f (g α) ≡ g (f α)_, which would > > >> work if maps were `Distributive` [1]. > > >> > > >> It looks to me as though the following definition might work: > > >> > > >> distribute = unionsWith union . mapWithKey (fmap . singleton) > > >> > > >> — And it works on simple examples. _(I checked the law `distribute ∘ > > >> distribute ≡ id` — it appears to be the only law required.)_ > > >> > > >> Is this definition correct? Is it already known and defined > > >> elsewhere? > > >> > > >> [1]: > > >> > https://hackage.haskell.org/package/distributive-0.6.2.1/docs/Data-Distributive.html#t:Distributive > > > > > > Hi Ignat, > > > > > > TL;DR: No and no. > > > > > > The documentation says that every distributive functor is of the form > > > (->) x for some x, and (Map a) is not like this. > > > > > > If Maps were a category, what is the identity morphism? > > > > > > Let's put the Ord constraint on the keys aside, Tom Smeding has already > > > commented on that. Next, a Map is always finite, hence let's pretend > > > that we are working inside the category of finite types and functions. > > > Then the problems of missing identity and missing Ord go away. Once > > > that all types are finite, we can assume an enumerator. That is, each > > > type x has an operation > > > enumerate :: [x] > > > which we will use to construct the inverse of > > > flip Map.lookup :: Map a b -> a -> Maybe b > > > thereby showing that a Map is nothing but a memoized version of a > > > Kleisli map (a -> Maybe b). Convince yourself that Map concatenation > > > has the same semantics as Kleisli composition (<=<). Given a Kleisli > > > map k between finite types, we build a Map as follows. > > > \k -> Map.fromList (enumerate >>= (\a -> maybe [] (pure.(,) a) (k a))) > > > > > > With that knowledge, we can answer your question by deciding: Is the > > > Kleisli category of the Maybe monad on finite types Cartesian closed? > > > Short answer: It is not even Cartesian. > > > There is an adjunction between the categories (->) and (Kleisli m) for > > > every monad m, where > > > * The left adjoint functor takes > > > types x to x, > > > functions f to return.f > > > * The right adjoint functor takes > > > types x to m x, > > > Kleisli maps f to (=<<) f > > > Right adjoint functors preserve all existing limits, which includes > > > products. Therefore, if (Kleisli m) has binary products, then m must > > > preserve them. So if P x y was the product of x and y in Kleisli m, > > > then m (P x y) would be isomorphic to (m x,m y). This seems not to hold > > > for m = Maybe: I can not imagine a type constructor P where > > > Maybe (P x y) ~ (Maybe x,Maybe y). > > > In particular, P can not be (,). The only sensible Kleisli projections > > > from (x,y) would be fst' = return.fst and snd' = return.snd. Now think > > > of two Kleisli maps f :: Bool -> Maybe x, g :: Bool -> Maybe y. Assume > > > that f True = Just x for some x and g True = Nothing. In order to > > > satisfy g True = (snd' <=< (f&&&g))True, the unique pair arrow (f&&&g) > > > would need to map True to Nothing, but then f True = (fst' <=< (f&&&g)) > > > True can not hold. We conclude that (Kleisli Maybe) does not even have > > > categorical products, so asking for Cartesian closure does not make > > > sense. > > > > > > You might ask for a weaker property: For every type x, ((,) x) is a > > > functor on (Kleisli Maybe). Indeed, the following works because ((,) x) > > > is a polynomial functor. > > > fmapKleisli :: Functor m => (a -> m b) -> (x,a) -> m (x,b) > > > fmapKleisli f (x,a) = fmap ((,) x) (f a) > > > Thus you may ask whether this functor has a right adjoint in the > > > Kleisli category of Maybe. This would be a type constructor g with a > > > natural isomorphism > > > > > > (x,a) -> Maybe b ~ a -> Maybe (g b). > > > > > > The first thing that comes to mind is to try > > > g b = x -> Maybe b and indeed djinn can provide two functions going > > > back and forth that have the right type, but they do not establish an > > > isomorphism. I doubt there is such a right adjoint g, but can not prove > > > it at the moment. The idea is that a function (x,a) -> Maybe b may > > > decide for Nothing depending on both x and a, and therefore the image > > > function under the isomorphism must map every a to Just (g b) and delay > > > the Nothing-decision to the g b. But for the reverse isomorphism you > > > can have functions that do not always return Just (g b) and there is no > > > preimage for these. > > > > > > Regards, > > > Olaf > > > > > > > > > > > > _______________________________________________ > > > 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 olf at aatal-apotheke.de Sat Jan 9 22:40:51 2021 From: olf at aatal-apotheke.de (Olaf Klinke) Date: Sat, 09 Jan 2021 23:40:51 +0100 Subject: [Haskell-cafe] A quick question about distribution of finite maps. In-Reply-To: References: Message-ID: <7746ffa9ced97f507e095f4e8477d6b5acf2bd78.camel@aatal-apotheke.de> On Sat, 2021-01-09 at 22:26 +0100, MigMit wrote: > Actually, it's pretty easy to construct a type `P x y`, so that Maybe > (P x y) ~ (Maybe x, Maybe y). It would be > > data OneOrBoth x y = Left' x | Right' y | Both x y > > The isomorphism is, I think, obvious > > iso1 :: Maybe (OneOrBoth x y) -> (Maybe x, Maybe y) > iso1 Nothing = (Nothing, Nothing) > iso1 (Just (Left' x)) = (Just x, Nothing) > iso1 (Just (Right' y)) = (Nothing, Just y) > iso1 (Just (Both x y)) = (Just x, Just y) > > iso2 :: (Maybe x, Maybe y) -> Maybe (OneOrBoth x y) > iso2 = -- left as an excersize for the reader > > And indeed, "OneOrBoth" would be a cartesian product functor in the > category of finite types (and maps). I stand corrected. Below is the full code, in case anyone wants to play with it. import Control.Arrow ((&&&)) -- due to David Feuer data OneOrBoth x y = Left' x | Right' y | Both x y iso2 :: (Maybe x,Maybe y) -> Maybe (OneOrBoth x y) iso2 p = case p of (Nothing,Nothing) -> Nothing (Just x,Nothing) -> (Just (Left' x)) (Nothing,Just y) -> (Just (Right' y)) (Just x, Just y) -> (Just (Both x y)) -- (OneOrBoth x) is a functor on Kleisli Maybe fmapKleisli :: (a -> Maybe b) -> OneOrBoth x a -> Maybe (OneOrBoth x b) fmapKleisli k (Left' x) = Just (Left' x) fmapKleisli k (Right' a) = fmap Right' (k a) fmapKleisli k (Both x a) = fmap (Both x) (k a) -- is OneOrBoth the cartesian product? Seems so: pairKleisli :: (a -> Maybe x) -> (a -> Maybe y) -> a -> Maybe (OneOrBoth x y) pairKleisli f g = iso2 . (f &&& g) fstMaybe :: OneOrBoth x y -> Maybe x fstMaybe (Left' x) = Just x fstMaybe (Both x _) = Just x fstMaybe (Right' _) = Nothing sndMaybe :: OneOrBoth x y -> Maybe y sndMaybe (Left' _) = Nothing sndMaybe (Right' y) = Just y sndMaybe (Both _ y) = Just y > > But it won't be cartesian closed. If it were, then for any finite X > and Y we should have > > Maybe (X^Y) ~ > () -> Maybe (X^Y) ~ > OneOrBoth () Y -> Maybe X ~ > (() -> Maybe X, Y -> Maybe X, ((), Y) -> Maybe X) ~ > (Maybe X, Y -> Maybe X, Y -> Maybe X) > > so > > X^Y ~ (X, Y -> Maybe X, Y -> Maybe X) > > But then > > Z -> Maybe (X^Y) ~ > Z -> (Maybe X, Y -> Maybe X, Y -> Maybe X) ~ > (Z -> Maybe X, (Z, Y) -> Maybe X, (Z, Y) -> Maybe X) ~ > > and > > OneOrBoth Z Y -> Maybe X ~ > (Z -> Maybe X, Y -> Maybe X, (Z, Y) -> Maybe X) > > We see that those aren't the same, they have a different number of > elements, so, no luck. Doesn't this chain of isomorphisms require () to be the terminal object, or did you take () as synonym for the terminal object in the category? For example, there are several functions of the type Bool -> Maybe (). So the terminal object in Kleisli Maybe would be Void, because Maybe Void ~ (). We'd need to make fields in OneOrBoth strict to have an isomorphism OneOrBoth Void a ~ a, just as the true categorical product in (->) is the strict pair. Olaf > > > On 9 Jan 2021, at 22:01, Olaf Klinke wrote: > > > > > Hello! > > > > > > Finite maps from `"containers" Data.Map` look like they may form > > > a > > > Cartesian closed category. So it makes sense to ask if the rule > > > _α ⇸ > > > (β ⇸ γ) ≡ ⟨α; β⟩ ⇸ γ ≡ ⟨β; α⟩ ⇸ γ ≡ β ⇸ (α ⇸ γ)_ that holds in > > > such > > > categories does hold for finite maps. Note that, a map being a > > > functor, this also may be seen as _f (g α) ≡ g (f α)_, which > > > would > > > work if maps were `Distributive` [1]. > > > > > > It looks to me as though the following definition might work: > > > > > > distribute = unionsWith union . mapWithKey (fmap . singleton) > > > > > > — And it works on simple examples. _(I checked the law > > > `distribute ∘ > > > distribute ≡ id` — it appears to be the only law required.)_ > > > > > > Is this definition correct? Is it already known and defined > > > elsewhere? > > > > > > [1]: > > > https://hackage.haskell.org/package/distributive-0.6.2.1/docs/Data-Distributive.html#t:Distributive > > > > Hi Ignat, > > > > TL;DR: No and no. > > > > The documentation says that every distributive functor is of the > > form > > (->) x for some x, and (Map a) is not like this. > > > > If Maps were a category, what is the identity morphism? > > > > Let's put the Ord constraint on the keys aside, Tom Smeding has > > already > > commented on that. Next, a Map is always finite, hence let's > > pretend > > that we are working inside the category of finite types and > > functions. > > Then the problems of missing identity and missing Ord go away. Once > > that all types are finite, we can assume an enumerator. That is, > > each > > type x has an operation > > enumerate :: [x] > > which we will use to construct the inverse of > > flip Map.lookup :: Map a b -> a -> Maybe b > > thereby showing that a Map is nothing but a memoized version of a > > Kleisli map (a -> Maybe b). Convince yourself that Map > > concatenation > > has the same semantics as Kleisli composition (<=<). Given a > > Kleisli > > map k between finite types, we build a Map as follows. > > \k -> Map.fromList (enumerate >>= (\a -> maybe [] (pure.(,) a) (k > > a))) > > > > With that knowledge, we can answer your question by deciding: Is > > the > > Kleisli category of the Maybe monad on finite types Cartesian > > closed? > > Short answer: It is not even Cartesian. > > There is an adjunction between the categories (->) and (Kleisli m) > > for > > every monad m, where > > * The left adjoint functor takes > > types x to x, > > functions f to return.f > > * The right adjoint functor takes > > types x to m x, > > Kleisli maps f to (=<<) f > > Right adjoint functors preserve all existing limits, which includes > > products. Therefore, if (Kleisli m) has binary products, then m > > must > > preserve them. So if P x y was the product of x and y in Kleisli m, > > then m (P x y) would be isomorphic to (m x,m y). This seems not to > > hold > > for m = Maybe: I can not imagine a type constructor P where > > Maybe (P x y) ~ (Maybe x,Maybe y). > > In particular, P can not be (,). The only sensible Kleisli > > projections > > from (x,y) would be fst' = return.fst and snd' = return.snd. Now > > think > > of two Kleisli maps f :: Bool -> Maybe x, g :: Bool -> Maybe y. > > Assume > > that f True = Just x for some x and g True = Nothing. In order to > > satisfy g True = (snd' <=< (f&&&g))True, the unique pair arrow > > (f&&&g) > > would need to map True to Nothing, but then f True = (fst' <=< > > (f&&&g)) > > True can not hold. We conclude that (Kleisli Maybe) does not even > > have > > categorical products, so asking for Cartesian closure does not make > > sense. > > > > You might ask for a weaker property: For every type x, ((,) x) is a > > functor on (Kleisli Maybe). Indeed, the following works because > > ((,) x) > > is a polynomial functor. > > fmapKleisli :: Functor m => (a -> m b) -> (x,a) -> m (x,b) > > fmapKleisli f (x,a) = fmap ((,) x) (f a) > > Thus you may ask whether this functor has a right adjoint in the > > Kleisli category of Maybe. This would be a type constructor g with > > a > > natural isomorphism > > > > (x,a) -> Maybe b ~ a -> Maybe (g b). > > > > The first thing that comes to mind is to try > > g b = x -> Maybe b and indeed djinn can provide two functions going > > back and forth that have the right type, but they do not establish > > an > > isomorphism. I doubt there is such a right adjoint g, but can not > > prove > > it at the moment. The idea is that a function (x,a) -> Maybe b may > > decide for Nothing depending on both x and a, and therefore the > > image > > function under the isomorphism must map every a to Just (g b) and > > delay > > the Nothing-decision to the g b. But for the reverse isomorphism > > you > > can have functions that do not always return Just (g b) and there > > is no > > preimage for these. > > > > Regards, > > Olaf > > > > > > > > _______________________________________________ > > 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 migmit at gmail.com Sat Jan 9 22:45:41 2021 From: migmit at gmail.com (MigMit) Date: Sat, 9 Jan 2021 23:45:41 +0100 Subject: [Haskell-cafe] A quick question about distribution of finite maps. In-Reply-To: <7746ffa9ced97f507e095f4e8477d6b5acf2bd78.camel@aatal-apotheke.de> References: <7746ffa9ced97f507e095f4e8477d6b5acf2bd78.camel@aatal-apotheke.de> Message-ID: No, my arrows and isomorphisms are all in the original category, not the Kleisli one — although the "X^Y" is the exponent in the Kleisli category. > On 9 Jan 2021, at 23:40, Olaf Klinke wrote: > > On Sat, 2021-01-09 at 22:26 +0100, MigMit wrote: >> Actually, it's pretty easy to construct a type `P x y`, so that Maybe >> (P x y) ~ (Maybe x, Maybe y). It would be >> >> data OneOrBoth x y = Left' x | Right' y | Both x y >> >> The isomorphism is, I think, obvious >> >> iso1 :: Maybe (OneOrBoth x y) -> (Maybe x, Maybe y) >> iso1 Nothing = (Nothing, Nothing) >> iso1 (Just (Left' x)) = (Just x, Nothing) >> iso1 (Just (Right' y)) = (Nothing, Just y) >> iso1 (Just (Both x y)) = (Just x, Just y) >> >> iso2 :: (Maybe x, Maybe y) -> Maybe (OneOrBoth x y) >> iso2 = -- left as an excersize for the reader >> >> And indeed, "OneOrBoth" would be a cartesian product functor in the >> category of finite types (and maps). > > I stand corrected. Below is the full code, in case anyone wants to play > with it. > > import Control.Arrow ((&&&)) > > -- due to David Feuer > data OneOrBoth x y = Left' x | Right' y | Both x y > > iso2 :: (Maybe x,Maybe y) -> Maybe (OneOrBoth x y) > iso2 p = case p of > (Nothing,Nothing) -> Nothing > (Just x,Nothing) -> (Just (Left' x)) > (Nothing,Just y) -> (Just (Right' y)) > (Just x, Just y) -> (Just (Both x y)) > > -- (OneOrBoth x) is a functor on Kleisli Maybe > fmapKleisli :: (a -> Maybe b) -> > OneOrBoth x a -> Maybe (OneOrBoth x b) > fmapKleisli k (Left' x) = Just (Left' x) > fmapKleisli k (Right' a) = fmap Right' (k a) > fmapKleisli k (Both x a) = fmap (Both x) (k a) > > -- is OneOrBoth the cartesian product? Seems so: > > pairKleisli :: (a -> Maybe x) -> > (a -> Maybe y) -> > a -> Maybe (OneOrBoth x y) > pairKleisli f g = iso2 . (f &&& g) > > fstMaybe :: OneOrBoth x y -> Maybe x > fstMaybe (Left' x) = Just x > fstMaybe (Both x _) = Just x > fstMaybe (Right' _) = Nothing > > sndMaybe :: OneOrBoth x y -> Maybe y > sndMaybe (Left' _) = Nothing > sndMaybe (Right' y) = Just y > sndMaybe (Both _ y) = Just y > >> >> But it won't be cartesian closed. If it were, then for any finite X >> and Y we should have >> >> Maybe (X^Y) ~ >> () -> Maybe (X^Y) ~ >> OneOrBoth () Y -> Maybe X ~ >> (() -> Maybe X, Y -> Maybe X, ((), Y) -> Maybe X) ~ >> (Maybe X, Y -> Maybe X, Y -> Maybe X) >> >> so >> >> X^Y ~ (X, Y -> Maybe X, Y -> Maybe X) >> >> But then >> >> Z -> Maybe (X^Y) ~ >> Z -> (Maybe X, Y -> Maybe X, Y -> Maybe X) ~ >> (Z -> Maybe X, (Z, Y) -> Maybe X, (Z, Y) -> Maybe X) ~ >> >> and >> >> OneOrBoth Z Y -> Maybe X ~ >> (Z -> Maybe X, Y -> Maybe X, (Z, Y) -> Maybe X) >> >> We see that those aren't the same, they have a different number of >> elements, so, no luck. > > Doesn't this chain of isomorphisms require () to be the terminal > object, or did you take () as synonym for the terminal object in the > category? For example, there are several functions of the type > Bool -> Maybe (). > So the terminal object in Kleisli Maybe would be Void, because Maybe > Void ~ (). We'd need to make fields in OneOrBoth strict to have an > isomorphism OneOrBoth Void a ~ a, just as the true categorical product > in (->) is the strict pair. > > Olaf > >> >>> On 9 Jan 2021, at 22:01, Olaf Klinke wrote: >>> >>>> Hello! >>>> >>>> Finite maps from `"containers" Data.Map` look like they may form >>>> a >>>> Cartesian closed category. So it makes sense to ask if the rule >>>> _α ⇸ >>>> (β ⇸ γ) ≡ ⟨α; β⟩ ⇸ γ ≡ ⟨β; α⟩ ⇸ γ ≡ β ⇸ (α ⇸ γ)_ that holds in >>>> such >>>> categories does hold for finite maps. Note that, a map being a >>>> functor, this also may be seen as _f (g α) ≡ g (f α)_, which >>>> would >>>> work if maps were `Distributive` [1]. >>>> >>>> It looks to me as though the following definition might work: >>>> >>>> distribute = unionsWith union . mapWithKey (fmap . singleton) >>>> >>>> — And it works on simple examples. _(I checked the law >>>> `distribute ∘ >>>> distribute ≡ id` — it appears to be the only law required.)_ >>>> >>>> Is this definition correct? Is it already known and defined >>>> elsewhere? >>>> >>>> [1]: >>>> https://hackage.haskell.org/package/distributive-0.6.2.1/docs/Data-Distributive.html#t:Distributive >>> >>> Hi Ignat, >>> >>> TL;DR: No and no. >>> >>> The documentation says that every distributive functor is of the >>> form >>> (->) x for some x, and (Map a) is not like this. >>> >>> If Maps were a category, what is the identity morphism? >>> >>> Let's put the Ord constraint on the keys aside, Tom Smeding has >>> already >>> commented on that. Next, a Map is always finite, hence let's >>> pretend >>> that we are working inside the category of finite types and >>> functions. >>> Then the problems of missing identity and missing Ord go away. Once >>> that all types are finite, we can assume an enumerator. That is, >>> each >>> type x has an operation >>> enumerate :: [x] >>> which we will use to construct the inverse of >>> flip Map.lookup :: Map a b -> a -> Maybe b >>> thereby showing that a Map is nothing but a memoized version of a >>> Kleisli map (a -> Maybe b). Convince yourself that Map >>> concatenation >>> has the same semantics as Kleisli composition (<=<). Given a >>> Kleisli >>> map k between finite types, we build a Map as follows. >>> \k -> Map.fromList (enumerate >>= (\a -> maybe [] (pure.(,) a) (k >>> a))) >>> >>> With that knowledge, we can answer your question by deciding: Is >>> the >>> Kleisli category of the Maybe monad on finite types Cartesian >>> closed? >>> Short answer: It is not even Cartesian. >>> There is an adjunction between the categories (->) and (Kleisli m) >>> for >>> every monad m, where >>> * The left adjoint functor takes >>> types x to x, >>> functions f to return.f >>> * The right adjoint functor takes >>> types x to m x, >>> Kleisli maps f to (=<<) f >>> Right adjoint functors preserve all existing limits, which includes >>> products. Therefore, if (Kleisli m) has binary products, then m >>> must >>> preserve them. So if P x y was the product of x and y in Kleisli m, >>> then m (P x y) would be isomorphic to (m x,m y). This seems not to >>> hold >>> for m = Maybe: I can not imagine a type constructor P where >>> Maybe (P x y) ~ (Maybe x,Maybe y). >>> In particular, P can not be (,). The only sensible Kleisli >>> projections >>> from (x,y) would be fst' = return.fst and snd' = return.snd. Now >>> think >>> of two Kleisli maps f :: Bool -> Maybe x, g :: Bool -> Maybe y. >>> Assume >>> that f True = Just x for some x and g True = Nothing. In order to >>> satisfy g True = (snd' <=< (f&&&g))True, the unique pair arrow >>> (f&&&g) >>> would need to map True to Nothing, but then f True = (fst' <=< >>> (f&&&g)) >>> True can not hold. We conclude that (Kleisli Maybe) does not even >>> have >>> categorical products, so asking for Cartesian closure does not make >>> sense. >>> >>> You might ask for a weaker property: For every type x, ((,) x) is a >>> functor on (Kleisli Maybe). Indeed, the following works because >>> ((,) x) >>> is a polynomial functor. >>> fmapKleisli :: Functor m => (a -> m b) -> (x,a) -> m (x,b) >>> fmapKleisli f (x,a) = fmap ((,) x) (f a) >>> Thus you may ask whether this functor has a right adjoint in the >>> Kleisli category of Maybe. This would be a type constructor g with >>> a >>> natural isomorphism >>> >>> (x,a) -> Maybe b ~ a -> Maybe (g b). >>> >>> The first thing that comes to mind is to try >>> g b = x -> Maybe b and indeed djinn can provide two functions going >>> back and forth that have the right type, but they do not establish >>> an >>> isomorphism. I doubt there is such a right adjoint g, but can not >>> prove >>> it at the moment. The idea is that a function (x,a) -> Maybe b may >>> decide for Nothing depending on both x and a, and therefore the >>> image >>> function under the isomorphism must map every a to Just (g b) and >>> delay >>> the Nothing-decision to the g b. But for the reverse isomorphism >>> you >>> can have functions that do not always return Just (g b) and there >>> is no >>> preimage for these. >>> >>> Regards, >>> Olaf >>> >>> >>> >>> _______________________________________________ >>> 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 david.feuer at gmail.com Sat Jan 9 23:04:26 2021 From: david.feuer at gmail.com (David Feuer) Date: Sat, 9 Jan 2021 18:04:26 -0500 Subject: [Haskell-cafe] A quick question about distribution of finite maps. In-Reply-To: <7746ffa9ced97f507e095f4e8477d6b5acf2bd78.camel@aatal-apotheke.de> References: <7746ffa9ced97f507e095f4e8477d6b5acf2bd78.camel@aatal-apotheke.de> Message-ID: `These` is not my own invention. It's in the `these` package. On Sat, Jan 9, 2021, 5:41 PM Olaf Klinke wrote: > On Sat, 2021-01-09 at 22:26 +0100, MigMit wrote: > > Actually, it's pretty easy to construct a type `P x y`, so that Maybe > > (P x y) ~ (Maybe x, Maybe y). It would be > > > > data OneOrBoth x y = Left' x | Right' y | Both x y > > > > The isomorphism is, I think, obvious > > > > iso1 :: Maybe (OneOrBoth x y) -> (Maybe x, Maybe y) > > iso1 Nothing = (Nothing, Nothing) > > iso1 (Just (Left' x)) = (Just x, Nothing) > > iso1 (Just (Right' y)) = (Nothing, Just y) > > iso1 (Just (Both x y)) = (Just x, Just y) > > > > iso2 :: (Maybe x, Maybe y) -> Maybe (OneOrBoth x y) > > iso2 = -- left as an excersize for the reader > > > > And indeed, "OneOrBoth" would be a cartesian product functor in the > > category of finite types (and maps). > > I stand corrected. Below is the full code, in case anyone wants to play > with it. > > import Control.Arrow ((&&&)) > > -- due to David Feuer > data OneOrBoth x y = Left' x | Right' y | Both x y > > iso2 :: (Maybe x,Maybe y) -> Maybe (OneOrBoth x y) > iso2 p = case p of > (Nothing,Nothing) -> Nothing > (Just x,Nothing) -> (Just (Left' x)) > (Nothing,Just y) -> (Just (Right' y)) > (Just x, Just y) -> (Just (Both x y)) > > -- (OneOrBoth x) is a functor on Kleisli Maybe > fmapKleisli :: (a -> Maybe b) -> > OneOrBoth x a -> Maybe (OneOrBoth x b) > fmapKleisli k (Left' x) = Just (Left' x) > fmapKleisli k (Right' a) = fmap Right' (k a) > fmapKleisli k (Both x a) = fmap (Both x) (k a) > > -- is OneOrBoth the cartesian product? Seems so: > > pairKleisli :: (a -> Maybe x) -> > (a -> Maybe y) -> > a -> Maybe (OneOrBoth x y) > pairKleisli f g = iso2 . (f &&& g) > > fstMaybe :: OneOrBoth x y -> Maybe x > fstMaybe (Left' x) = Just x > fstMaybe (Both x _) = Just x > fstMaybe (Right' _) = Nothing > > sndMaybe :: OneOrBoth x y -> Maybe y > sndMaybe (Left' _) = Nothing > sndMaybe (Right' y) = Just y > sndMaybe (Both _ y) = Just y > > > > > But it won't be cartesian closed. If it were, then for any finite X > > and Y we should have > > > > Maybe (X^Y) ~ > > () -> Maybe (X^Y) ~ > > OneOrBoth () Y -> Maybe X ~ > > (() -> Maybe X, Y -> Maybe X, ((), Y) -> Maybe X) ~ > > (Maybe X, Y -> Maybe X, Y -> Maybe X) > > > > so > > > > X^Y ~ (X, Y -> Maybe X, Y -> Maybe X) > > > > But then > > > > Z -> Maybe (X^Y) ~ > > Z -> (Maybe X, Y -> Maybe X, Y -> Maybe X) ~ > > (Z -> Maybe X, (Z, Y) -> Maybe X, (Z, Y) -> Maybe X) ~ > > > > and > > > > OneOrBoth Z Y -> Maybe X ~ > > (Z -> Maybe X, Y -> Maybe X, (Z, Y) -> Maybe X) > > > > We see that those aren't the same, they have a different number of > > elements, so, no luck. > > Doesn't this chain of isomorphisms require () to be the terminal > object, or did you take () as synonym for the terminal object in the > category? For example, there are several functions of the type > Bool -> Maybe (). > So the terminal object in Kleisli Maybe would be Void, because Maybe > Void ~ (). We'd need to make fields in OneOrBoth strict to have an > isomorphism OneOrBoth Void a ~ a, just as the true categorical product > in (->) is the strict pair. > > Olaf > > > > > > On 9 Jan 2021, at 22:01, Olaf Klinke wrote: > > > > > > > Hello! > > > > > > > > Finite maps from `"containers" Data.Map` look like they may form > > > > a > > > > Cartesian closed category. So it makes sense to ask if the rule > > > > _α ⇸ > > > > (β ⇸ γ) ≡ ⟨α; β⟩ ⇸ γ ≡ ⟨β; α⟩ ⇸ γ ≡ β ⇸ (α ⇸ γ)_ that holds in > > > > such > > > > categories does hold for finite maps. Note that, a map being a > > > > functor, this also may be seen as _f (g α) ≡ g (f α)_, which > > > > would > > > > work if maps were `Distributive` [1]. > > > > > > > > It looks to me as though the following definition might work: > > > > > > > > distribute = unionsWith union . mapWithKey (fmap . singleton) > > > > > > > > — And it works on simple examples. _(I checked the law > > > > `distribute ∘ > > > > distribute ≡ id` — it appears to be the only law required.)_ > > > > > > > > Is this definition correct? Is it already known and defined > > > > elsewhere? > > > > > > > > [1]: > > > > > https://hackage.haskell.org/package/distributive-0.6.2.1/docs/Data-Distributive.html#t:Distributive > > > > > > Hi Ignat, > > > > > > TL;DR: No and no. > > > > > > The documentation says that every distributive functor is of the > > > form > > > (->) x for some x, and (Map a) is not like this. > > > > > > If Maps were a category, what is the identity morphism? > > > > > > Let's put the Ord constraint on the keys aside, Tom Smeding has > > > already > > > commented on that. Next, a Map is always finite, hence let's > > > pretend > > > that we are working inside the category of finite types and > > > functions. > > > Then the problems of missing identity and missing Ord go away. Once > > > that all types are finite, we can assume an enumerator. That is, > > > each > > > type x has an operation > > > enumerate :: [x] > > > which we will use to construct the inverse of > > > flip Map.lookup :: Map a b -> a -> Maybe b > > > thereby showing that a Map is nothing but a memoized version of a > > > Kleisli map (a -> Maybe b). Convince yourself that Map > > > concatenation > > > has the same semantics as Kleisli composition (<=<). Given a > > > Kleisli > > > map k between finite types, we build a Map as follows. > > > \k -> Map.fromList (enumerate >>= (\a -> maybe [] (pure.(,) a) (k > > > a))) > > > > > > With that knowledge, we can answer your question by deciding: Is > > > the > > > Kleisli category of the Maybe monad on finite types Cartesian > > > closed? > > > Short answer: It is not even Cartesian. > > > There is an adjunction between the categories (->) and (Kleisli m) > > > for > > > every monad m, where > > > * The left adjoint functor takes > > > types x to x, > > > functions f to return.f > > > * The right adjoint functor takes > > > types x to m x, > > > Kleisli maps f to (=<<) f > > > Right adjoint functors preserve all existing limits, which includes > > > products. Therefore, if (Kleisli m) has binary products, then m > > > must > > > preserve them. So if P x y was the product of x and y in Kleisli m, > > > then m (P x y) would be isomorphic to (m x,m y). This seems not to > > > hold > > > for m = Maybe: I can not imagine a type constructor P where > > > Maybe (P x y) ~ (Maybe x,Maybe y). > > > In particular, P can not be (,). The only sensible Kleisli > > > projections > > > from (x,y) would be fst' = return.fst and snd' = return.snd. Now > > > think > > > of two Kleisli maps f :: Bool -> Maybe x, g :: Bool -> Maybe y. > > > Assume > > > that f True = Just x for some x and g True = Nothing. In order to > > > satisfy g True = (snd' <=< (f&&&g))True, the unique pair arrow > > > (f&&&g) > > > would need to map True to Nothing, but then f True = (fst' <=< > > > (f&&&g)) > > > True can not hold. We conclude that (Kleisli Maybe) does not even > > > have > > > categorical products, so asking for Cartesian closure does not make > > > sense. > > > > > > You might ask for a weaker property: For every type x, ((,) x) is a > > > functor on (Kleisli Maybe). Indeed, the following works because > > > ((,) x) > > > is a polynomial functor. > > > fmapKleisli :: Functor m => (a -> m b) -> (x,a) -> m (x,b) > > > fmapKleisli f (x,a) = fmap ((,) x) (f a) > > > Thus you may ask whether this functor has a right adjoint in the > > > Kleisli category of Maybe. This would be a type constructor g with > > > a > > > natural isomorphism > > > > > > (x,a) -> Maybe b ~ a -> Maybe (g b). > > > > > > The first thing that comes to mind is to try > > > g b = x -> Maybe b and indeed djinn can provide two functions going > > > back and forth that have the right type, but they do not establish > > > an > > > isomorphism. I doubt there is such a right adjoint g, but can not > > > prove > > > it at the moment. The idea is that a function (x,a) -> Maybe b may > > > decide for Nothing depending on both x and a, and therefore the > > > image > > > function under the isomorphism must map every a to Just (g b) and > > > delay > > > the Nothing-decision to the g b. But for the reverse isomorphism > > > you > > > can have functions that do not always return Just (g b) and there > > > is no > > > preimage for these. > > > > > > Regards, > > > Olaf > > > > > > > > > > > > _______________________________________________ > > > 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 olf at aatal-apotheke.de Sun Jan 10 07:16:38 2021 From: olf at aatal-apotheke.de (Olaf Klinke) Date: Sun, 10 Jan 2021 08:16:38 +0100 Subject: [Haskell-cafe] A quick question about distribution of finite maps. In-Reply-To: References: <7746ffa9ced97f507e095f4e8477d6b5acf2bd78.camel@aatal-apotheke.de> Message-ID: <651e7eb0f0f75978fa58dc6194fe572b61f4a668.camel@aatal-apotheke.de> On Sat, 2021-01-09 at 18:04 -0500, David Feuer wrote: > `These` is not my own invention. It's in the `these` package. Then please interpret my "due to David Feuer" as "brought into this discussion by David Feuer". I wonder whether These has ever been linked to categorical products in Kleisli Maybe before. There are Data.These.Combinators.justHere and justThere which are the same as my fstMaybe and sndMaybe. But combinators resulting in pairKleisli and iso1 seem to be missing from the these package. Olaf > > On Sat, Jan 9, 2021, 5:41 PM Olaf Klinke > wrote: > > > On Sat, 2021-01-09 at 22:26 +0100, MigMit wrote: > > > Actually, it's pretty easy to construct a type `P x y`, so that > > > Maybe > > > (P x y) ~ (Maybe x, Maybe y). It would be > > > > > > data OneOrBoth x y = Left' x | Right' y | Both x y > > > > > > The isomorphism is, I think, obvious > > > > > > iso1 :: Maybe (OneOrBoth x y) -> (Maybe x, Maybe y) > > > iso1 Nothing = (Nothing, Nothing) > > > iso1 (Just (Left' x)) = (Just x, Nothing) > > > iso1 (Just (Right' y)) = (Nothing, Just y) > > > iso1 (Just (Both x y)) = (Just x, Just y) > > > > > > iso2 :: (Maybe x, Maybe y) -> Maybe (OneOrBoth x y) > > > iso2 = -- left as an excersize for the reader > > > > > > And indeed, "OneOrBoth" would be a cartesian product functor in > > > the > > > category of finite types (and maps). > > > > I stand corrected. Below is the full code, in case anyone wants to > > play > > with it. > > > > import Control.Arrow ((&&&)) > > > > -- due to David Feuer > > data OneOrBoth x y = Left' x | Right' y | Both x y > > > > iso2 :: (Maybe x,Maybe y) -> Maybe (OneOrBoth x y) > > iso2 p = case p of > > (Nothing,Nothing) -> Nothing > > (Just x,Nothing) -> (Just (Left' x)) > > (Nothing,Just y) -> (Just (Right' y)) > > (Just x, Just y) -> (Just (Both x y)) > > > > -- (OneOrBoth x) is a functor on Kleisli Maybe > > fmapKleisli :: (a -> Maybe b) -> > > OneOrBoth x a -> Maybe (OneOrBoth x b) > > fmapKleisli k (Left' x) = Just (Left' x) > > fmapKleisli k (Right' a) = fmap Right' (k a) > > fmapKleisli k (Both x a) = fmap (Both x) (k a) > > > > -- is OneOrBoth the cartesian product? Seems so: > > > > pairKleisli :: (a -> Maybe x) -> > > (a -> Maybe y) -> > > a -> Maybe (OneOrBoth x y) > > pairKleisli f g = iso2 . (f &&& g) > > > > fstMaybe :: OneOrBoth x y -> Maybe x > > fstMaybe (Left' x) = Just x > > fstMaybe (Both x _) = Just x > > fstMaybe (Right' _) = Nothing > > > > sndMaybe :: OneOrBoth x y -> Maybe y > > sndMaybe (Left' _) = Nothing > > sndMaybe (Right' y) = Just y > > sndMaybe (Both _ y) = Just y > > > > > But it won't be cartesian closed. If it were, then for any finite > > > X > > > and Y we should have > > > > > > Maybe (X^Y) ~ > > > () -> Maybe (X^Y) ~ > > > OneOrBoth () Y -> Maybe X ~ > > > (() -> Maybe X, Y -> Maybe X, ((), Y) -> Maybe X) ~ > > > (Maybe X, Y -> Maybe X, Y -> Maybe X) > > > > > > so > > > > > > X^Y ~ (X, Y -> Maybe X, Y -> Maybe X) > > > > > > But then > > > > > > Z -> Maybe (X^Y) ~ > > > Z -> (Maybe X, Y -> Maybe X, Y -> Maybe X) ~ > > > (Z -> Maybe X, (Z, Y) -> Maybe X, (Z, Y) -> Maybe X) ~ > > > > > > and > > > > > > OneOrBoth Z Y -> Maybe X ~ > > > (Z -> Maybe X, Y -> Maybe X, (Z, Y) -> Maybe X) > > > > > > We see that those aren't the same, they have a different number > > > of > > > elements, so, no luck. > > > > Doesn't this chain of isomorphisms require () to be the terminal > > object, or did you take () as synonym for the terminal object in > > the > > category? For example, there are several functions of the type > > Bool -> Maybe (). > > So the terminal object in Kleisli Maybe would be Void, because > > Maybe > > Void ~ (). We'd need to make fields in OneOrBoth strict to have an > > isomorphism OneOrBoth Void a ~ a, just as the true categorical > > product > > in (->) is the strict pair. > > > > Olaf > > > > > > On 9 Jan 2021, at 22:01, Olaf Klinke > > > > wrote: > > > > > > > > > Hello! > > > > > > > > > > Finite maps from `"containers" Data.Map` look like they may > > > > > form > > > > > a > > > > > Cartesian closed category. So it makes sense to ask if the > > > > > rule > > > > > _α ⇸ > > > > > (β ⇸ γ) ≡ ⟨α; β⟩ ⇸ γ ≡ ⟨β; α⟩ ⇸ γ ≡ β ⇸ (α ⇸ γ)_ that holds > > > > > in > > > > > such > > > > > categories does hold for finite maps. Note that, a map being > > > > > a > > > > > functor, this also may be seen as _f (g α) ≡ g (f α)_, which > > > > > would > > > > > work if maps were `Distributive` [1]. > > > > > > > > > > It looks to me as though the following definition might work: > > > > > > > > > > distribute = unionsWith union . mapWithKey (fmap . > > > > > singleton) > > > > > > > > > > — And it works on simple examples. _(I checked the law > > > > > `distribute ∘ > > > > > distribute ≡ id` — it appears to be the only law required.)_ > > > > > > > > > > Is this definition correct? Is it already known and defined > > > > > elsewhere? > > > > > > > > > > [1]: > > > > > > > https://hackage.haskell.org/package/distributive-0.6.2.1/docs/Data-Distributive.html#t:Distributive > > > > Hi Ignat, > > > > > > > > TL;DR: No and no. > > > > > > > > The documentation says that every distributive functor is of > > > > the > > > > form > > > > (->) x for some x, and (Map a) is not like this. > > > > > > > > If Maps were a category, what is the identity morphism? > > > > > > > > Let's put the Ord constraint on the keys aside, Tom Smeding has > > > > already > > > > commented on that. Next, a Map is always finite, hence let's > > > > pretend > > > > that we are working inside the category of finite types and > > > > functions. > > > > Then the problems of missing identity and missing Ord go away. > > > > Once > > > > that all types are finite, we can assume an enumerator. That > > > > is, > > > > each > > > > type x has an operation > > > > enumerate :: [x] > > > > which we will use to construct the inverse of > > > > flip Map.lookup :: Map a b -> a -> Maybe b > > > > thereby showing that a Map is nothing but a memoized version of > > > > a > > > > Kleisli map (a -> Maybe b). Convince yourself that Map > > > > concatenation > > > > has the same semantics as Kleisli composition (<=<). Given a > > > > Kleisli > > > > map k between finite types, we build a Map as follows. > > > > \k -> Map.fromList (enumerate >>= (\a -> maybe [] (pure.(,) a) > > > > (k > > > > a))) > > > > > > > > With that knowledge, we can answer your question by deciding: > > > > Is > > > > the > > > > Kleisli category of the Maybe monad on finite types Cartesian > > > > closed? > > > > Short answer: It is not even Cartesian. > > > > There is an adjunction between the categories (->) and (Kleisli > > > > m) > > > > for > > > > every monad m, where > > > > * The left adjoint functor takes > > > > types x to x, > > > > functions f to return.f > > > > * The right adjoint functor takes > > > > types x to m x, > > > > Kleisli maps f to (=<<) f > > > > Right adjoint functors preserve all existing limits, which > > > > includes > > > > products. Therefore, if (Kleisli m) has binary products, then m > > > > must > > > > preserve them. So if P x y was the product of x and y in > > > > Kleisli m, > > > > then m (P x y) would be isomorphic to (m x,m y). This seems not > > > > to > > > > hold > > > > for m = Maybe: I can not imagine a type constructor P where > > > > Maybe (P x y) ~ (Maybe x,Maybe y). > > > > In particular, P can not be (,). The only sensible Kleisli > > > > projections > > > > from (x,y) would be fst' = return.fst and snd' = return.snd. > > > > Now > > > > think > > > > of two Kleisli maps f :: Bool -> Maybe x, g :: Bool -> Maybe y. > > > > Assume > > > > that f True = Just x for some x and g True = Nothing. In order > > > > to > > > > satisfy g True = (snd' <=< (f&&&g))True, the unique pair arrow > > > > (f&&&g) > > > > would need to map True to Nothing, but then f True = (fst' <=< > > > > (f&&&g)) > > > > True can not hold. We conclude that (Kleisli Maybe) does not > > > > even > > > > have > > > > categorical products, so asking for Cartesian closure does not > > > > make > > > > sense. > > > > > > > > You might ask for a weaker property: For every type x, ((,) x) > > > > is a > > > > functor on (Kleisli Maybe). Indeed, the following works because > > > > ((,) x) > > > > is a polynomial functor. > > > > fmapKleisli :: Functor m => (a -> m b) -> (x,a) -> m (x,b) > > > > fmapKleisli f (x,a) = fmap ((,) x) (f a) > > > > Thus you may ask whether this functor has a right adjoint in > > > > the > > > > Kleisli category of Maybe. This would be a type constructor g > > > > with > > > > a > > > > natural isomorphism > > > > > > > > (x,a) -> Maybe b ~ a -> Maybe (g b). > > > > > > > > The first thing that comes to mind is to try > > > > g b = x -> Maybe b and indeed djinn can provide two functions > > > > going > > > > back and forth that have the right type, but they do not > > > > establish > > > > an > > > > isomorphism. I doubt there is such a right adjoint g, but can > > > > not > > > > prove > > > > it at the moment. The idea is that a function (x,a) -> Maybe b > > > > may > > > > decide for Nothing depending on both x and a, and therefore the > > > > image > > > > function under the isomorphism must map every a to Just (g b) > > > > and > > > > delay > > > > the Nothing-decision to the g b. But for the reverse > > > > isomorphism > > > > you > > > > can have functions that do not always return Just (g b) and > > > > there > > > > is no > > > > preimage for these. > > > > > > > > Regards, > > > > Olaf > > > > > > > > > > > > > > > > _______________________________________________ > > > > 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 david.feuer at gmail.com Sun Jan 10 07:19:29 2021 From: david.feuer at gmail.com (David Feuer) Date: Sun, 10 Jan 2021 02:19:29 -0500 Subject: [Haskell-cafe] A quick question about distribution of finite maps. In-Reply-To: <651e7eb0f0f75978fa58dc6194fe572b61f4a668.camel@aatal-apotheke.de> References: <7746ffa9ced97f507e095f4e8477d6b5acf2bd78.camel@aatal-apotheke.de> <651e7eb0f0f75978fa58dc6194fe572b61f4a668.camel@aatal-apotheke.de> Message-ID: I just don't want to take credit for anyone else's work. I have a very vague recollection that Emily Pillmore may have looked at some related categorical stuff, but I could easily be mistaken. On Sun, Jan 10, 2021, 2:16 AM Olaf Klinke wrote: > On Sat, 2021-01-09 at 18:04 -0500, David Feuer wrote: > > `These` is not my own invention. It's in the `these` package. > > Then please interpret my "due to David Feuer" as "brought into this > discussion by David Feuer". I wonder whether These has ever been linked > to categorical products in Kleisli Maybe before. There are > Data.These.Combinators.justHere and justThere which are the same as my > fstMaybe and sndMaybe. But combinators resulting in pairKleisli and > iso1 seem to be missing from the these package. > > Olaf > > > > > On Sat, Jan 9, 2021, 5:41 PM Olaf Klinke > > wrote: > > > > > On Sat, 2021-01-09 at 22:26 +0100, MigMit wrote: > > > > Actually, it's pretty easy to construct a type `P x y`, so that > > > > Maybe > > > > (P x y) ~ (Maybe x, Maybe y). It would be > > > > > > > > data OneOrBoth x y = Left' x | Right' y | Both x y > > > > > > > > The isomorphism is, I think, obvious > > > > > > > > iso1 :: Maybe (OneOrBoth x y) -> (Maybe x, Maybe y) > > > > iso1 Nothing = (Nothing, Nothing) > > > > iso1 (Just (Left' x)) = (Just x, Nothing) > > > > iso1 (Just (Right' y)) = (Nothing, Just y) > > > > iso1 (Just (Both x y)) = (Just x, Just y) > > > > > > > > iso2 :: (Maybe x, Maybe y) -> Maybe (OneOrBoth x y) > > > > iso2 = -- left as an excersize for the reader > > > > > > > > And indeed, "OneOrBoth" would be a cartesian product functor in > > > > the > > > > category of finite types (and maps). > > > > > > I stand corrected. Below is the full code, in case anyone wants to > > > play > > > with it. > > > > > > import Control.Arrow ((&&&)) > > > > > > -- due to David Feuer > > > data OneOrBoth x y = Left' x | Right' y | Both x y > > > > > > iso2 :: (Maybe x,Maybe y) -> Maybe (OneOrBoth x y) > > > iso2 p = case p of > > > (Nothing,Nothing) -> Nothing > > > (Just x,Nothing) -> (Just (Left' x)) > > > (Nothing,Just y) -> (Just (Right' y)) > > > (Just x, Just y) -> (Just (Both x y)) > > > > > > -- (OneOrBoth x) is a functor on Kleisli Maybe > > > fmapKleisli :: (a -> Maybe b) -> > > > OneOrBoth x a -> Maybe (OneOrBoth x b) > > > fmapKleisli k (Left' x) = Just (Left' x) > > > fmapKleisli k (Right' a) = fmap Right' (k a) > > > fmapKleisli k (Both x a) = fmap (Both x) (k a) > > > > > > -- is OneOrBoth the cartesian product? Seems so: > > > > > > pairKleisli :: (a -> Maybe x) -> > > > (a -> Maybe y) -> > > > a -> Maybe (OneOrBoth x y) > > > pairKleisli f g = iso2 . (f &&& g) > > > > > > fstMaybe :: OneOrBoth x y -> Maybe x > > > fstMaybe (Left' x) = Just x > > > fstMaybe (Both x _) = Just x > > > fstMaybe (Right' _) = Nothing > > > > > > sndMaybe :: OneOrBoth x y -> Maybe y > > > sndMaybe (Left' _) = Nothing > > > sndMaybe (Right' y) = Just y > > > sndMaybe (Both _ y) = Just y > > > > > > > But it won't be cartesian closed. If it were, then for any finite > > > > X > > > > and Y we should have > > > > > > > > Maybe (X^Y) ~ > > > > () -> Maybe (X^Y) ~ > > > > OneOrBoth () Y -> Maybe X ~ > > > > (() -> Maybe X, Y -> Maybe X, ((), Y) -> Maybe X) ~ > > > > (Maybe X, Y -> Maybe X, Y -> Maybe X) > > > > > > > > so > > > > > > > > X^Y ~ (X, Y -> Maybe X, Y -> Maybe X) > > > > > > > > But then > > > > > > > > Z -> Maybe (X^Y) ~ > > > > Z -> (Maybe X, Y -> Maybe X, Y -> Maybe X) ~ > > > > (Z -> Maybe X, (Z, Y) -> Maybe X, (Z, Y) -> Maybe X) ~ > > > > > > > > and > > > > > > > > OneOrBoth Z Y -> Maybe X ~ > > > > (Z -> Maybe X, Y -> Maybe X, (Z, Y) -> Maybe X) > > > > > > > > We see that those aren't the same, they have a different number > > > > of > > > > elements, so, no luck. > > > > > > Doesn't this chain of isomorphisms require () to be the terminal > > > object, or did you take () as synonym for the terminal object in > > > the > > > category? For example, there are several functions of the type > > > Bool -> Maybe (). > > > So the terminal object in Kleisli Maybe would be Void, because > > > Maybe > > > Void ~ (). We'd need to make fields in OneOrBoth strict to have an > > > isomorphism OneOrBoth Void a ~ a, just as the true categorical > > > product > > > in (->) is the strict pair. > > > > > > Olaf > > > > > > > > On 9 Jan 2021, at 22:01, Olaf Klinke > > > > > wrote: > > > > > > > > > > > Hello! > > > > > > > > > > > > Finite maps from `"containers" Data.Map` look like they may > > > > > > form > > > > > > a > > > > > > Cartesian closed category. So it makes sense to ask if the > > > > > > rule > > > > > > _α ⇸ > > > > > > (β ⇸ γ) ≡ ⟨α; β⟩ ⇸ γ ≡ ⟨β; α⟩ ⇸ γ ≡ β ⇸ (α ⇸ γ)_ that holds > > > > > > in > > > > > > such > > > > > > categories does hold for finite maps. Note that, a map being > > > > > > a > > > > > > functor, this also may be seen as _f (g α) ≡ g (f α)_, which > > > > > > would > > > > > > work if maps were `Distributive` [1]. > > > > > > > > > > > > It looks to me as though the following definition might work: > > > > > > > > > > > > distribute = unionsWith union . mapWithKey (fmap . > > > > > > singleton) > > > > > > > > > > > > — And it works on simple examples. _(I checked the law > > > > > > `distribute ∘ > > > > > > distribute ≡ id` — it appears to be the only law required.)_ > > > > > > > > > > > > Is this definition correct? Is it already known and defined > > > > > > elsewhere? > > > > > > > > > > > > [1]: > > > > > > > > > > https://hackage.haskell.org/package/distributive-0.6.2.1/docs/Data-Distributive.html#t:Distributive > > > > > Hi Ignat, > > > > > > > > > > TL;DR: No and no. > > > > > > > > > > The documentation says that every distributive functor is of > > > > > the > > > > > form > > > > > (->) x for some x, and (Map a) is not like this. > > > > > > > > > > If Maps were a category, what is the identity morphism? > > > > > > > > > > Let's put the Ord constraint on the keys aside, Tom Smeding has > > > > > already > > > > > commented on that. Next, a Map is always finite, hence let's > > > > > pretend > > > > > that we are working inside the category of finite types and > > > > > functions. > > > > > Then the problems of missing identity and missing Ord go away. > > > > > Once > > > > > that all types are finite, we can assume an enumerator. That > > > > > is, > > > > > each > > > > > type x has an operation > > > > > enumerate :: [x] > > > > > which we will use to construct the inverse of > > > > > flip Map.lookup :: Map a b -> a -> Maybe b > > > > > thereby showing that a Map is nothing but a memoized version of > > > > > a > > > > > Kleisli map (a -> Maybe b). Convince yourself that Map > > > > > concatenation > > > > > has the same semantics as Kleisli composition (<=<). Given a > > > > > Kleisli > > > > > map k between finite types, we build a Map as follows. > > > > > \k -> Map.fromList (enumerate >>= (\a -> maybe [] (pure.(,) a) > > > > > (k > > > > > a))) > > > > > > > > > > With that knowledge, we can answer your question by deciding: > > > > > Is > > > > > the > > > > > Kleisli category of the Maybe monad on finite types Cartesian > > > > > closed? > > > > > Short answer: It is not even Cartesian. > > > > > There is an adjunction between the categories (->) and (Kleisli > > > > > m) > > > > > for > > > > > every monad m, where > > > > > * The left adjoint functor takes > > > > > types x to x, > > > > > functions f to return.f > > > > > * The right adjoint functor takes > > > > > types x to m x, > > > > > Kleisli maps f to (=<<) f > > > > > Right adjoint functors preserve all existing limits, which > > > > > includes > > > > > products. Therefore, if (Kleisli m) has binary products, then m > > > > > must > > > > > preserve them. So if P x y was the product of x and y in > > > > > Kleisli m, > > > > > then m (P x y) would be isomorphic to (m x,m y). This seems not > > > > > to > > > > > hold > > > > > for m = Maybe: I can not imagine a type constructor P where > > > > > Maybe (P x y) ~ (Maybe x,Maybe y). > > > > > In particular, P can not be (,). The only sensible Kleisli > > > > > projections > > > > > from (x,y) would be fst' = return.fst and snd' = return.snd. > > > > > Now > > > > > think > > > > > of two Kleisli maps f :: Bool -> Maybe x, g :: Bool -> Maybe y. > > > > > Assume > > > > > that f True = Just x for some x and g True = Nothing. In order > > > > > to > > > > > satisfy g True = (snd' <=< (f&&&g))True, the unique pair arrow > > > > > (f&&&g) > > > > > would need to map True to Nothing, but then f True = (fst' <=< > > > > > (f&&&g)) > > > > > True can not hold. We conclude that (Kleisli Maybe) does not > > > > > even > > > > > have > > > > > categorical products, so asking for Cartesian closure does not > > > > > make > > > > > sense. > > > > > > > > > > You might ask for a weaker property: For every type x, ((,) x) > > > > > is a > > > > > functor on (Kleisli Maybe). Indeed, the following works because > > > > > ((,) x) > > > > > is a polynomial functor. > > > > > fmapKleisli :: Functor m => (a -> m b) -> (x,a) -> m (x,b) > > > > > fmapKleisli f (x,a) = fmap ((,) x) (f a) > > > > > Thus you may ask whether this functor has a right adjoint in > > > > > the > > > > > Kleisli category of Maybe. This would be a type constructor g > > > > > with > > > > > a > > > > > natural isomorphism > > > > > > > > > > (x,a) -> Maybe b ~ a -> Maybe (g b). > > > > > > > > > > The first thing that comes to mind is to try > > > > > g b = x -> Maybe b and indeed djinn can provide two functions > > > > > going > > > > > back and forth that have the right type, but they do not > > > > > establish > > > > > an > > > > > isomorphism. I doubt there is such a right adjoint g, but can > > > > > not > > > > > prove > > > > > it at the moment. The idea is that a function (x,a) -> Maybe b > > > > > may > > > > > decide for Nothing depending on both x and a, and therefore the > > > > > image > > > > > function under the isomorphism must map every a to Just (g b) > > > > > and > > > > > delay > > > > > the Nothing-decision to the g b. But for the reverse > > > > > isomorphism > > > > > you > > > > > can have functions that do not always return Just (g b) and > > > > > there > > > > > is no > > > > > preimage for these. > > > > > > > > > > Regards, > > > > > Olaf > > > > > > > > > > > > > > > > > > > > _______________________________________________ > > > > > 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 jack at jackkelly.name Sun Jan 10 07:54:40 2021 From: jack at jackkelly.name (jack at jackkelly.name) Date: Sun, 10 Jan 2021 07:54:40 GMT Subject: [Haskell-cafe] A quick question about distribution of finite maps. In-Reply-To: References: <7746ffa9ced97f507e095f4e8477d6b5acf2bd78.camel@aatal-apotheke.de> <651e7eb0f0f75978fa58dc6194fe572b61f4a668.camel@aatal-apotheke.de> Message-ID: You may be thinking of https://hackage.haskell.org/package/smash and related packages. -- Jack January 10, 2021 5:19 PM, "David Feuer" wrote: > I just don't want to take credit for anyone else's work. I have a very vague recollection that > Emily Pillmore may have looked at some related categorical stuff, but I could easily be mistaken. > > On Sun, Jan 10, 2021, 2:16 AM Olaf Klinke wrote: > >> On Sat, 2021-01-09 at 18:04 -0500, David Feuer wrote: >>> `These` is not my own invention. It's in the `these` package. >> >> Then please interpret my "due to David Feuer" as "brought into this >> discussion by David Feuer". I wonder whether These has ever been linked >> to categorical products in Kleisli Maybe before. There are >> Data.These.Combinators.justHere and justThere which are the same as my >> fstMaybe and sndMaybe. But combinators resulting in pairKleisli and >> iso1 seem to be missing from the these package. >> >> Olaf >> >>> >>> On Sat, Jan 9, 2021, 5:41 PM Olaf Klinke >>> wrote: >>> >>>> On Sat, 2021-01-09 at 22:26 +0100, MigMit wrote: >>>>> Actually, it's pretty easy to construct a type `P x y`, so that >>>>> Maybe >>>>> (P x y) ~ (Maybe x, Maybe y). It would be >>>>> >>>>> data OneOrBoth x y = Left' x | Right' y | Both x y >>>>> >>>>> The isomorphism is, I think, obvious >>>>> >>>>> iso1 :: Maybe (OneOrBoth x y) -> (Maybe x, Maybe y) >>>>> iso1 Nothing = (Nothing, Nothing) >>>>> iso1 (Just (Left' x)) = (Just x, Nothing) >>>>> iso1 (Just (Right' y)) = (Nothing, Just y) >>>>> iso1 (Just (Both x y)) = (Just x, Just y) >>>>> >>>>> iso2 :: (Maybe x, Maybe y) -> Maybe (OneOrBoth x y) >>>>> iso2 = -- left as an excersize for the reader >>>>> >>>>> And indeed, "OneOrBoth" would be a cartesian product functor in >>>>> the >>>>> category of finite types (and maps). >>>> >>>> I stand corrected. Below is the full code, in case anyone wants to >>>> play >>>> with it. >>>> >>>> import Control.Arrow ((&&&)) >>>> >>>> -- due to David Feuer >>>> data OneOrBoth x y = Left' x | Right' y | Both x y >>>> >>>> iso2 :: (Maybe x,Maybe y) -> Maybe (OneOrBoth x y) >>>> iso2 p = case p of >>>> (Nothing,Nothing) -> Nothing >>>> (Just x,Nothing) -> (Just (Left' x)) >>>> (Nothing,Just y) -> (Just (Right' y)) >>>> (Just x, Just y) -> (Just (Both x y)) >>>> >>>> -- (OneOrBoth x) is a functor on Kleisli Maybe >>>> fmapKleisli :: (a -> Maybe b) -> >>>> OneOrBoth x a -> Maybe (OneOrBoth x b) >>>> fmapKleisli k (Left' x) = Just (Left' x) >>>> fmapKleisli k (Right' a) = fmap Right' (k a) >>>> fmapKleisli k (Both x a) = fmap (Both x) (k a) >>>> >>>> -- is OneOrBoth the cartesian product? Seems so: >>>> >>>> pairKleisli :: (a -> Maybe x) -> >>>> (a -> Maybe y) -> >>>> a -> Maybe (OneOrBoth x y) >>>> pairKleisli f g = iso2 . (f &&& g) >>>> >>>> fstMaybe :: OneOrBoth x y -> Maybe x >>>> fstMaybe (Left' x) = Just x >>>> fstMaybe (Both x _) = Just x >>>> fstMaybe (Right' _) = Nothing >>>> >>>> sndMaybe :: OneOrBoth x y -> Maybe y >>>> sndMaybe (Left' _) = Nothing >>>> sndMaybe (Right' y) = Just y >>>> sndMaybe (Both _ y) = Just y >>>> >>>>> But it won't be cartesian closed. If it were, then for any finite >>>>> X >>>>> and Y we should have >>>>> >>>>> Maybe (X^Y) ~ >>>>> () -> Maybe (X^Y) ~ >>>>> OneOrBoth () Y -> Maybe X ~ >>>>> (() -> Maybe X, Y -> Maybe X, ((), Y) -> Maybe X) ~ >>>>> (Maybe X, Y -> Maybe X, Y -> Maybe X) >>>>> >>>>> so >>>>> >>>>> X^Y ~ (X, Y -> Maybe X, Y -> Maybe X) >>>>> >>>>> But then >>>>> >>>>> Z -> Maybe (X^Y) ~ >>>>> Z -> (Maybe X, Y -> Maybe X, Y -> Maybe X) ~ >>>>> (Z -> Maybe X, (Z, Y) -> Maybe X, (Z, Y) -> Maybe X) ~ >>>>> >>>>> and >>>>> >>>>> OneOrBoth Z Y -> Maybe X ~ >>>>> (Z -> Maybe X, Y -> Maybe X, (Z, Y) -> Maybe X) >>>>> >>>>> We see that those aren't the same, they have a different number >>>>> of >>>>> elements, so, no luck. >>>> >>>> Doesn't this chain of isomorphisms require () to be the terminal >>>> object, or did you take () as synonym for the terminal object in >>>> the >>>> category? For example, there are several functions of the type >>>> Bool -> Maybe (). >>>> So the terminal object in Kleisli Maybe would be Void, because >>>> Maybe >>>> Void ~ (). We'd need to make fields in OneOrBoth strict to have an >>>> isomorphism OneOrBoth Void a ~ a, just as the true categorical >>>> product >>>> in (->) is the strict pair. >>>> >>>> Olaf >>>> >>>>>> On 9 Jan 2021, at 22:01, Olaf Klinke >>>>>> wrote: >>>>>> >>>>>>> Hello! >>>>>>> >>>>>>> Finite maps from `"containers" Data.Map` look like they may >>>>>>> form >>>>>>> a >>>>>>> Cartesian closed category. So it makes sense to ask if the >>>>>>> rule >>>>>>> _α ⇸ >>>>>>> (β ⇸ γ) ≡ ⟨α; β⟩ ⇸ γ ≡ ⟨β; α⟩ ⇸ γ ≡ β ⇸ (α ⇸ γ)_ that holds >>>>>>> in >>>>>>> such >>>>>>> categories does hold for finite maps. Note that, a map being >>>>>>> a >>>>>>> functor, this also may be seen as _f (g α) ≡ g (f α)_, which >>>>>>> would >>>>>>> work if maps were `Distributive` [1]. >>>>>>> >>>>>>> It looks to me as though the following definition might work: >>>>>>> >>>>>>> distribute = unionsWith union . mapWithKey (fmap . >>>>>>> singleton) >>>>>>> >>>>>>> — And it works on simple examples. _(I checked the law >>>>>>> `distribute ∘ >>>>>>> distribute ≡ id` — it appears to be the only law required.)_ >>>>>>> >>>>>>> Is this definition correct? Is it already known and defined >>>>>>> elsewhere? >>>>>>> >>>>>>> [1]: >>>>>>> >>>> >> https://hackage.haskell.org/package/distributive-0.6.2.1/docs/Data-Distributive.html#t:Distributive >>>>>> Hi Ignat, >>>>>> >>>>>> TL;DR: No and no. >>>>>> >>>>>> The documentation says that every distributive functor is of >>>>>> the >>>>>> form >>>>>> (->) x for some x, and (Map a) is not like this. >>>>>> >>>>>> If Maps were a category, what is the identity morphism? >>>>>> >>>>>> Let's put the Ord constraint on the keys aside, Tom Smeding has >>>>>> already >>>>>> commented on that. Next, a Map is always finite, hence let's >>>>>> pretend >>>>>> that we are working inside the category of finite types and >>>>>> functions. >>>>>> Then the problems of missing identity and missing Ord go away. >>>>>> Once >>>>>> that all types are finite, we can assume an enumerator. That >>>>>> is, >>>>>> each >>>>>> type x has an operation >>>>>> enumerate :: [x] >>>>>> which we will use to construct the inverse of >>>>>> flip Map.lookup :: Map a b -> a -> Maybe b >>>>>> thereby showing that a Map is nothing but a memoized version of >>>>>> a >>>>>> Kleisli map (a -> Maybe b). Convince yourself that Map >>>>>> concatenation >>>>>> has the same semantics as Kleisli composition (<=<). Given a >>>>>> Kleisli >>>>>> map k between finite types, we build a Map as follows. >>>>>> \k -> Map.fromList (enumerate >>= (\a -> maybe [] (pure.(,) a) >>>>>> (k >>>>>> a))) >>>>>> >>>>>> With that knowledge, we can answer your question by deciding: >>>>>> Is >>>>>> the >>>>>> Kleisli category of the Maybe monad on finite types Cartesian >>>>>> closed? >>>>>> Short answer: It is not even Cartesian. >>>>>> There is an adjunction between the categories (->) and (Kleisli >>>>>> m) >>>>>> for >>>>>> every monad m, where >>>>>> * The left adjoint functor takes >>>>>> types x to x, >>>>>> functions f to return.f >>>>>> * The right adjoint functor takes >>>>>> types x to m x, >>>>>> Kleisli maps f to (=<<) f >>>>>> Right adjoint functors preserve all existing limits, which >>>>>> includes >>>>>> products. Therefore, if (Kleisli m) has binary products, then m >>>>>> must >>>>>> preserve them. So if P x y was the product of x and y in >>>>>> Kleisli m, >>>>>> then m (P x y) would be isomorphic to (m x,m y). This seems not >>>>>> to >>>>>> hold >>>>>> for m = Maybe: I can not imagine a type constructor P where >>>>>> Maybe (P x y) ~ (Maybe x,Maybe y). >>>>>> In particular, P can not be (,). The only sensible Kleisli >>>>>> projections >>>>>> from (x,y) would be fst' = return.fst and snd' = return.snd. >>>>>> Now >>>>>> think >>>>>> of two Kleisli maps f :: Bool -> Maybe x, g :: Bool -> Maybe y. >>>>>> Assume >>>>>> that f True = Just x for some x and g True = Nothing. In order >>>>>> to >>>>>> satisfy g True = (snd' <=< (f&&&g))True, the unique pair arrow >>>>>> (f&&&g) >>>>>> would need to map True to Nothing, but then f True = (fst' <=< >>>>>> (f&&&g)) >>>>>> True can not hold. We conclude that (Kleisli Maybe) does not >>>>>> even >>>>>> have >>>>>> categorical products, so asking for Cartesian closure does not >>>>>> make >>>>>> sense. >>>>>> >>>>>> You might ask for a weaker property: For every type x, ((,) x) >>>>>> is a >>>>>> functor on (Kleisli Maybe). Indeed, the following works because >>>>>> ((,) x) >>>>>> is a polynomial functor. >>>>>> fmapKleisli :: Functor m => (a -> m b) -> (x,a) -> m (x,b) >>>>>> fmapKleisli f (x,a) = fmap ((,) x) (f a) >>>>>> Thus you may ask whether this functor has a right adjoint in >>>>>> the >>>>>> Kleisli category of Maybe. This would be a type constructor g >>>>>> with >>>>>> a >>>>>> natural isomorphism >>>>>> >>>>>> (x,a) -> Maybe b ~ a -> Maybe (g b). >>>>>> >>>>>> The first thing that comes to mind is to try >>>>>> g b = x -> Maybe b and indeed djinn can provide two functions >>>>>> going >>>>>> back and forth that have the right type, but they do not >>>>>> establish >>>>>> an >>>>>> isomorphism. I doubt there is such a right adjoint g, but can >>>>>> not >>>>>> prove >>>>>> it at the moment. The idea is that a function (x,a) -> Maybe b >>>>>> may >>>>>> decide for Nothing depending on both x and a, and therefore the >>>>>> image >>>>>> function under the isomorphism must map every a to Just (g b) >>>>>> and >>>>>> delay >>>>>> the Nothing-decision to the g b. But for the reverse >>>>>> isomorphism >>>>>> you >>>>>> can have functions that do not always return Just (g b) and >>>>>> there >>>>>> is no >>>>>> preimage for these. >>>>>> >>>>>> Regards, >>>>>> Olaf >>>>>> >>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> 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 david.feuer at gmail.com Sun Jan 10 11:53:31 2021 From: david.feuer at gmail.com (David Feuer) Date: Sun, 10 Jan 2021 06:53:31 -0500 Subject: [Haskell-cafe] A quick question about distribution of finite maps. In-Reply-To: References: <7746ffa9ced97f507e095f4e8477d6b5acf2bd78.camel@aatal-apotheke.de> <651e7eb0f0f75978fa58dc6194fe572b61f4a668.camel@aatal-apotheke.de> Message-ID: You found it! See specifically the documentation for Data.Can. On Sun, Jan 10, 2021, 2:54 AM wrote: > You may be thinking of https://hackage.haskell.org/package/smash and > related packages. > > -- Jack > > January 10, 2021 5:19 PM, "David Feuer" wrote: > > > I just don't want to take credit for anyone else's work. I have a very > vague recollection that > > Emily Pillmore may have looked at some related categorical stuff, but I > could easily be mistaken. > > > > On Sun, Jan 10, 2021, 2:16 AM Olaf Klinke wrote: > > > >> On Sat, 2021-01-09 at 18:04 -0500, David Feuer wrote: > >>> `These` is not my own invention. It's in the `these` package. > >> > >> Then please interpret my "due to David Feuer" as "brought into this > >> discussion by David Feuer". I wonder whether These has ever been linked > >> to categorical products in Kleisli Maybe before. There are > >> Data.These.Combinators.justHere and justThere which are the same as my > >> fstMaybe and sndMaybe. But combinators resulting in pairKleisli and > >> iso1 seem to be missing from the these package. > >> > >> Olaf > >> > >>> > >>> On Sat, Jan 9, 2021, 5:41 PM Olaf Klinke > >>> wrote: > >>> > >>>> On Sat, 2021-01-09 at 22:26 +0100, MigMit wrote: > >>>>> Actually, it's pretty easy to construct a type `P x y`, so that > >>>>> Maybe > >>>>> (P x y) ~ (Maybe x, Maybe y). It would be > >>>>> > >>>>> data OneOrBoth x y = Left' x | Right' y | Both x y > >>>>> > >>>>> The isomorphism is, I think, obvious > >>>>> > >>>>> iso1 :: Maybe (OneOrBoth x y) -> (Maybe x, Maybe y) > >>>>> iso1 Nothing = (Nothing, Nothing) > >>>>> iso1 (Just (Left' x)) = (Just x, Nothing) > >>>>> iso1 (Just (Right' y)) = (Nothing, Just y) > >>>>> iso1 (Just (Both x y)) = (Just x, Just y) > >>>>> > >>>>> iso2 :: (Maybe x, Maybe y) -> Maybe (OneOrBoth x y) > >>>>> iso2 = -- left as an excersize for the reader > >>>>> > >>>>> And indeed, "OneOrBoth" would be a cartesian product functor in > >>>>> the > >>>>> category of finite types (and maps). > >>>> > >>>> I stand corrected. Below is the full code, in case anyone wants to > >>>> play > >>>> with it. > >>>> > >>>> import Control.Arrow ((&&&)) > >>>> > >>>> -- due to David Feuer > >>>> data OneOrBoth x y = Left' x | Right' y | Both x y > >>>> > >>>> iso2 :: (Maybe x,Maybe y) -> Maybe (OneOrBoth x y) > >>>> iso2 p = case p of > >>>> (Nothing,Nothing) -> Nothing > >>>> (Just x,Nothing) -> (Just (Left' x)) > >>>> (Nothing,Just y) -> (Just (Right' y)) > >>>> (Just x, Just y) -> (Just (Both x y)) > >>>> > >>>> -- (OneOrBoth x) is a functor on Kleisli Maybe > >>>> fmapKleisli :: (a -> Maybe b) -> > >>>> OneOrBoth x a -> Maybe (OneOrBoth x b) > >>>> fmapKleisli k (Left' x) = Just (Left' x) > >>>> fmapKleisli k (Right' a) = fmap Right' (k a) > >>>> fmapKleisli k (Both x a) = fmap (Both x) (k a) > >>>> > >>>> -- is OneOrBoth the cartesian product? Seems so: > >>>> > >>>> pairKleisli :: (a -> Maybe x) -> > >>>> (a -> Maybe y) -> > >>>> a -> Maybe (OneOrBoth x y) > >>>> pairKleisli f g = iso2 . (f &&& g) > >>>> > >>>> fstMaybe :: OneOrBoth x y -> Maybe x > >>>> fstMaybe (Left' x) = Just x > >>>> fstMaybe (Both x _) = Just x > >>>> fstMaybe (Right' _) = Nothing > >>>> > >>>> sndMaybe :: OneOrBoth x y -> Maybe y > >>>> sndMaybe (Left' _) = Nothing > >>>> sndMaybe (Right' y) = Just y > >>>> sndMaybe (Both _ y) = Just y > >>>> > >>>>> But it won't be cartesian closed. If it were, then for any finite > >>>>> X > >>>>> and Y we should have > >>>>> > >>>>> Maybe (X^Y) ~ > >>>>> () -> Maybe (X^Y) ~ > >>>>> OneOrBoth () Y -> Maybe X ~ > >>>>> (() -> Maybe X, Y -> Maybe X, ((), Y) -> Maybe X) ~ > >>>>> (Maybe X, Y -> Maybe X, Y -> Maybe X) > >>>>> > >>>>> so > >>>>> > >>>>> X^Y ~ (X, Y -> Maybe X, Y -> Maybe X) > >>>>> > >>>>> But then > >>>>> > >>>>> Z -> Maybe (X^Y) ~ > >>>>> Z -> (Maybe X, Y -> Maybe X, Y -> Maybe X) ~ > >>>>> (Z -> Maybe X, (Z, Y) -> Maybe X, (Z, Y) -> Maybe X) ~ > >>>>> > >>>>> and > >>>>> > >>>>> OneOrBoth Z Y -> Maybe X ~ > >>>>> (Z -> Maybe X, Y -> Maybe X, (Z, Y) -> Maybe X) > >>>>> > >>>>> We see that those aren't the same, they have a different number > >>>>> of > >>>>> elements, so, no luck. > >>>> > >>>> Doesn't this chain of isomorphisms require () to be the terminal > >>>> object, or did you take () as synonym for the terminal object in > >>>> the > >>>> category? For example, there are several functions of the type > >>>> Bool -> Maybe (). > >>>> So the terminal object in Kleisli Maybe would be Void, because > >>>> Maybe > >>>> Void ~ (). We'd need to make fields in OneOrBoth strict to have an > >>>> isomorphism OneOrBoth Void a ~ a, just as the true categorical > >>>> product > >>>> in (->) is the strict pair. > >>>> > >>>> Olaf > >>>> > >>>>>> On 9 Jan 2021, at 22:01, Olaf Klinke > >>>>>> wrote: > >>>>>> > >>>>>>> Hello! > >>>>>>> > >>>>>>> Finite maps from `"containers" Data.Map` look like they may > >>>>>>> form > >>>>>>> a > >>>>>>> Cartesian closed category. So it makes sense to ask if the > >>>>>>> rule > >>>>>>> _α ⇸ > >>>>>>> (β ⇸ γ) ≡ ⟨α; β⟩ ⇸ γ ≡ ⟨β; α⟩ ⇸ γ ≡ β ⇸ (α ⇸ γ)_ that holds > >>>>>>> in > >>>>>>> such > >>>>>>> categories does hold for finite maps. Note that, a map being > >>>>>>> a > >>>>>>> functor, this also may be seen as _f (g α) ≡ g (f α)_, which > >>>>>>> would > >>>>>>> work if maps were `Distributive` [1]. > >>>>>>> > >>>>>>> It looks to me as though the following definition might work: > >>>>>>> > >>>>>>> distribute = unionsWith union . mapWithKey (fmap . > >>>>>>> singleton) > >>>>>>> > >>>>>>> — And it works on simple examples. _(I checked the law > >>>>>>> `distribute ∘ > >>>>>>> distribute ≡ id` — it appears to be the only law required.)_ > >>>>>>> > >>>>>>> Is this definition correct? Is it already known and defined > >>>>>>> elsewhere? > >>>>>>> > >>>>>>> [1]: > >>>>>>> > >>>> > >> > https://hackage.haskell.org/package/distributive-0.6.2.1/docs/Data-Distributive.html#t:Distributive > >>>>>> Hi Ignat, > >>>>>> > >>>>>> TL;DR: No and no. > >>>>>> > >>>>>> The documentation says that every distributive functor is of > >>>>>> the > >>>>>> form > >>>>>> (->) x for some x, and (Map a) is not like this. > >>>>>> > >>>>>> If Maps were a category, what is the identity morphism? > >>>>>> > >>>>>> Let's put the Ord constraint on the keys aside, Tom Smeding has > >>>>>> already > >>>>>> commented on that. Next, a Map is always finite, hence let's > >>>>>> pretend > >>>>>> that we are working inside the category of finite types and > >>>>>> functions. > >>>>>> Then the problems of missing identity and missing Ord go away. > >>>>>> Once > >>>>>> that all types are finite, we can assume an enumerator. That > >>>>>> is, > >>>>>> each > >>>>>> type x has an operation > >>>>>> enumerate :: [x] > >>>>>> which we will use to construct the inverse of > >>>>>> flip Map.lookup :: Map a b -> a -> Maybe b > >>>>>> thereby showing that a Map is nothing but a memoized version of > >>>>>> a > >>>>>> Kleisli map (a -> Maybe b). Convince yourself that Map > >>>>>> concatenation > >>>>>> has the same semantics as Kleisli composition (<=<). Given a > >>>>>> Kleisli > >>>>>> map k between finite types, we build a Map as follows. > >>>>>> \k -> Map.fromList (enumerate >>= (\a -> maybe [] (pure.(,) a) > >>>>>> (k > >>>>>> a))) > >>>>>> > >>>>>> With that knowledge, we can answer your question by deciding: > >>>>>> Is > >>>>>> the > >>>>>> Kleisli category of the Maybe monad on finite types Cartesian > >>>>>> closed? > >>>>>> Short answer: It is not even Cartesian. > >>>>>> There is an adjunction between the categories (->) and (Kleisli > >>>>>> m) > >>>>>> for > >>>>>> every monad m, where > >>>>>> * The left adjoint functor takes > >>>>>> types x to x, > >>>>>> functions f to return.f > >>>>>> * The right adjoint functor takes > >>>>>> types x to m x, > >>>>>> Kleisli maps f to (=<<) f > >>>>>> Right adjoint functors preserve all existing limits, which > >>>>>> includes > >>>>>> products. Therefore, if (Kleisli m) has binary products, then m > >>>>>> must > >>>>>> preserve them. So if P x y was the product of x and y in > >>>>>> Kleisli m, > >>>>>> then m (P x y) would be isomorphic to (m x,m y). This seems not > >>>>>> to > >>>>>> hold > >>>>>> for m = Maybe: I can not imagine a type constructor P where > >>>>>> Maybe (P x y) ~ (Maybe x,Maybe y). > >>>>>> In particular, P can not be (,). The only sensible Kleisli > >>>>>> projections > >>>>>> from (x,y) would be fst' = return.fst and snd' = return.snd. > >>>>>> Now > >>>>>> think > >>>>>> of two Kleisli maps f :: Bool -> Maybe x, g :: Bool -> Maybe y. > >>>>>> Assume > >>>>>> that f True = Just x for some x and g True = Nothing. In order > >>>>>> to > >>>>>> satisfy g True = (snd' <=< (f&&&g))True, the unique pair arrow > >>>>>> (f&&&g) > >>>>>> would need to map True to Nothing, but then f True = (fst' <=< > >>>>>> (f&&&g)) > >>>>>> True can not hold. We conclude that (Kleisli Maybe) does not > >>>>>> even > >>>>>> have > >>>>>> categorical products, so asking for Cartesian closure does not > >>>>>> make > >>>>>> sense. > >>>>>> > >>>>>> You might ask for a weaker property: For every type x, ((,) x) > >>>>>> is a > >>>>>> functor on (Kleisli Maybe). Indeed, the following works because > >>>>>> ((,) x) > >>>>>> is a polynomial functor. > >>>>>> fmapKleisli :: Functor m => (a -> m b) -> (x,a) -> m (x,b) > >>>>>> fmapKleisli f (x,a) = fmap ((,) x) (f a) > >>>>>> Thus you may ask whether this functor has a right adjoint in > >>>>>> the > >>>>>> Kleisli category of Maybe. This would be a type constructor g > >>>>>> with > >>>>>> a > >>>>>> natural isomorphism > >>>>>> > >>>>>> (x,a) -> Maybe b ~ a -> Maybe (g b). > >>>>>> > >>>>>> The first thing that comes to mind is to try > >>>>>> g b = x -> Maybe b and indeed djinn can provide two functions > >>>>>> going > >>>>>> back and forth that have the right type, but they do not > >>>>>> establish > >>>>>> an > >>>>>> isomorphism. I doubt there is such a right adjoint g, but can > >>>>>> not > >>>>>> prove > >>>>>> it at the moment. The idea is that a function (x,a) -> Maybe b > >>>>>> may > >>>>>> decide for Nothing depending on both x and a, and therefore the > >>>>>> image > >>>>>> function under the isomorphism must map every a to Just (g b) > >>>>>> and > >>>>>> delay > >>>>>> the Nothing-decision to the g b. But for the reverse > >>>>>> isomorphism > >>>>>> you > >>>>>> can have functions that do not always return Just (g b) and > >>>>>> there > >>>>>> is no > >>>>>> preimage for these. > >>>>>> > >>>>>> Regards, > >>>>>> Olaf > >>>>>> > >>>>>> > >>>>>> > >>>>>> _______________________________________________ > >>>>>> 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 kindaro at gmail.com Sun Jan 10 12:09:14 2021 From: kindaro at gmail.com (Ignat Insarov) Date: Sun, 10 Jan 2021 17:09:14 +0500 Subject: [Haskell-cafe] A quick question about distribution of finite maps. In-Reply-To: References: <87v9c6b97x.fsf@hyperspace> Message-ID: Wow, this blew up overnight. Thank you Olaf and allies for attending to this topic. But I think there is a hidden mismatch of premises. So let me take a step back and look at things again, in order, from the ground up. > Hi Ignat, would you slow down a bit and tell us the idea behind your > question? > > You seem to expect Map forms a Cartesian closed category, and > want to know if the specific property of CCC holds ("functors of shape (a ⇸ -) > are distributive".) > > Could you explain that expectation step-by-step? For the first step, let us know > the category made from Maps more clearly. I mean, (1) what are the objects > of that category? (2) what are the morphisms? (3) how the identity morphisms > and the composition of morphisms are defined? > > The next step would be the "Cartesian" part. This category should have > direct product of any finite number of objects. What exactly are these, > and how do you define the projection morphisms (equivalents of `fst` and > `snd` in your category) and the product of morphisms (equivalent of `&&&`.) > > It's too rushed to think about CCC until these aren't clear. This is most fair. Being a software engineer and not a mathematician, I was hoping to avoid the scrutiny into what I was taking to be an accepted base line. It did not play out as I hoped, so let us rewind. As I offered previously: > The category **Haskell** of Haskell types and total functions is not a > suitable category for these entities, because you cannot represent subsets in > it, and subsets are kinda the whole point of the exercise. So I look at it as > though **Haskell** is a subcategory of **Set** and **Finite Set** — the > category of finite sets and finite maps — is another, although not entirely > disjoint subcategory. I take **Finite Set** to be Cartesian closed with the same product and exponent objects as its supercategory **Set**. Objections? None, excellent. Now to the mentioned mismatch. There are two philosophies: 1. Let us model perfect Mathematics in an imperfect programming language as best we can. 2. Let us have only as much Mathematics as we can so our programming language remains perfect. I employ the approach №1 here. Also, I already have a good idea of what I want to do, and I already have code that works. This makes proofs of non-existence somewhat less effective, in the sense that they cannot discourage me from exploring the matter. If the idea cannot work, I need to know in what cases it _does_ work. Actually, I find the idea that finite sets and functions may be represented in Haskell very attractive in general, so I think it is worth the effort to realize it in Haskell possibly better, even if perfect realization is unattainable _(and it is)_. That is not to say that I am going to ignore all objections. But I do want to recover as much as can be recovered. If not a category, maybe a semigroupoid? If not a monoid, maybe a semigroup? If we cannot model it in types, can we still use it with imaginary proofs? Maybe we can use a clever normalization to exclude pathologies? And so on. Particularly, I do not invoke the `Maybe` stuff — instead I say that an evaluation of a finite map on a value outside the set of its keys is an error and it is the responsibility of the programmer to prove that no such evaluations occur, even though they may pass the type checker. Yes, I give up type safety. ## Now to the technical details. We do not have subtypes in Haskell, but we do have subsets and finite maps — it is only that the type system does not know which subsets and finite maps are compatible. So, we depart from the category **Haskell** of types and total functions, and we allow instead that some values may be objects in our category **X** — notably the values of type `Set α`. * Now a function may be restricted to a finite set via `fromSet ∷ (k → a) → Set k → Map k a`, so there are arrows in **X** for every pair of an arrow of **Haskell** and a finite subset of an object of **Haskell** that has a total ordering _(or even mere decidable equality if we may sacrifice performance)_. * An identity arrow for a given finite set is then a restriction of `id` to that set. * Finite maps compose when the domain of one subsumes the range of the other via `fmap (g !) f`. * Terminal object is the unique singleton of type `Set ( )` or any uniquely isomorphic singleton of a type with a single nullary constructor. * The product of two finite sets is given by `cartesianProduct`, and projections are the appropriate restrictions of the usual `fst` and `snd`. * The exponential object is a finite set of all maps with the same domain and range. I went on and invented the definitions witnessing the requisite isomorphose: curry = mapKeysWith union fst ∘ mapWithKey (singleton ∘ snd) uncurry = unions ∘ mapWithKey (mapKeys ∘ (, )) They pass any example except the one Tom gave earlier, with an empty map. This establishes a Cartesian closed category of somewhat idealized entities. Can the realization of this category in Haskell be perfected to exclude pathologies by construction? Perhaps it is enough to normalize maps with `dropEmpty` before comparison? Seems worth some research. From tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk Sun Jan 10 12:15:24 2021 From: tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk (Tom Ellis) Date: Sun, 10 Jan 2021 12:15:24 +0000 Subject: [Haskell-cafe] A quick question about distribution of finite maps. In-Reply-To: References: <7746ffa9ced97f507e095f4e8477d6b5acf2bd78.camel@aatal-apotheke.de> <651e7eb0f0f75978fa58dc6194fe572b61f4a668.camel@aatal-apotheke.de> Message-ID: <20210110121524.GA11840@cloudinit-builder> And see https://www.youtube.com/watch?v=4aQlFMvKgdc for a related talk On Sun, Jan 10, 2021 at 06:53:31AM -0500, David Feuer wrote: > You found it! See specifically the documentation for Data.Can. > > On Sun, Jan 10, 2021, 2:54 AM wrote: > > > You may be thinking of https://hackage.haskell.org/package/smash and > > related packages. > > > > -- Jack > > > > January 10, 2021 5:19 PM, "David Feuer" wrote: > > > > > I just don't want to take credit for anyone else's work. I have a very > > vague recollecntion that > > > Emily Pillmore may have looked at some related categorical stuff, but I > > could easily be mistaken. > > > > > > On Sun, Jan 10, 2021, 2:16 AM Olaf Klinke wrote: > > > > > >> On Sat, 2021-01-09 at 18:04 -0500, David Feuer wrote: > > >>> `These` is not my own invention. It's in the `these` package. > > >> > > >> Then please interpret my "due to David Feuer" as "brought into this > > >> discussion by David Feuer". I wonder whether These has ever been linked > > >> to categorical products in Kleisli Maybe before. There are > > >> Data.These.Combinators.justHere and justThere which are the same as my > > >> fstMaybe and sndMaybe. But combinators resulting in pairKleisli and > > >> iso1 seem to be missing from the these package. > > >> > > >> Olaf > > >> > > >>> > > >>> On Sat, Jan 9, 2021, 5:41 PM Olaf Klinke > > >>> wrote: > > >>> > > >>>> On Sat, 2021-01-09 at 22:26 +0100, MigMit wrote: > > >>>>> Actually, it's pretty easy to construct a type `P x y`, so that > > >>>>> Maybe > > >>>>> (P x y) ~ (Maybe x, Maybe y). It would be > > >>>>> > > >>>>> data OneOrBoth x y = Left' x | Right' y | Both x y > > >>>>> > > >>>>> The isomorphism is, I think, obvious > > >>>>> > > >>>>> iso1 :: Maybe (OneOrBoth x y) -> (Maybe x, Maybe y) > > >>>>> iso1 Nothing = (Nothing, Nothing) > > >>>>> iso1 (Just (Left' x)) = (Just x, Nothing) > > >>>>> iso1 (Just (Right' y)) = (Nothing, Just y) > > >>>>> iso1 (Just (Both x y)) = (Just x, Just y) > > >>>>> > > >>>>> iso2 :: (Maybe x, Maybe y) -> Maybe (OneOrBoth x y) > > >>>>> iso2 = -- left as an excersize for the reader > > >>>>> > > >>>>> And indeed, "OneOrBoth" would be a cartesian product functor in > > >>>>> the > > >>>>> category of finite types (and maps). > > >>>> > > >>>> I stand corrected. Below is the full code, in case anyone wants to > > >>>> play > > >>>> with it. > > >>>> > > >>>> import Control.Arrow ((&&&)) > > >>>> > > >>>> -- due to David Feuer > > >>>> data OneOrBoth x y = Left' x | Right' y | Both x y > > >>>> > > >>>> iso2 :: (Maybe x,Maybe y) -> Maybe (OneOrBoth x y) > > >>>> iso2 p = case p of > > >>>> (Nothing,Nothing) -> Nothing > > >>>> (Just x,Nothing) -> (Just (Left' x)) > > >>>> (Nothing,Just y) -> (Just (Right' y)) > > >>>> (Just x, Just y) -> (Just (Both x y)) > > >>>> > > >>>> -- (OneOrBoth x) is a functor on Kleisli Maybe > > >>>> fmapKleisli :: (a -> Maybe b) -> > > >>>> OneOrBoth x a -> Maybe (OneOrBoth x b) > > >>>> fmapKleisli k (Left' x) = Just (Left' x) > > >>>> fmapKleisli k (Right' a) = fmap Right' (k a) > > >>>> fmapKleisli k (Both x a) = fmap (Both x) (k a) > > >>>> > > >>>> -- is OneOrBoth the cartesian product? Seems so: > > >>>> > > >>>> pairKleisli :: (a -> Maybe x) -> > > >>>> (a -> Maybe y) -> > > >>>> a -> Maybe (OneOrBoth x y) > > >>>> pairKleisli f g = iso2 . (f &&& g) > > >>>> > > >>>> fstMaybe :: OneOrBoth x y -> Maybe x > > >>>> fstMaybe (Left' x) = Just x > > >>>> fstMaybe (Both x _) = Just x > > >>>> fstMaybe (Right' _) = Nothing > > >>>> > > >>>> sndMaybe :: OneOrBoth x y -> Maybe y > > >>>> sndMaybe (Left' _) = Nothing > > >>>> sndMaybe (Right' y) = Just y > > >>>> sndMaybe (Both _ y) = Just y > > >>>> > > >>>>> But it won't be cartesian closed. If it were, then for any finite > > >>>>> X > > >>>>> and Y we should have > > >>>>> > > >>>>> Maybe (X^Y) ~ > > >>>>> () -> Maybe (X^Y) ~ > > >>>>> OneOrBoth () Y -> Maybe X ~ > > >>>>> (() -> Maybe X, Y -> Maybe X, ((), Y) -> Maybe X) ~ > > >>>>> (Maybe X, Y -> Maybe X, Y -> Maybe X) > > >>>>> > > >>>>> so > > >>>>> > > >>>>> X^Y ~ (X, Y -> Maybe X, Y -> Maybe X) > > >>>>> > > >>>>> But then > > >>>>> > > >>>>> Z -> Maybe (X^Y) ~ > > >>>>> Z -> (Maybe X, Y -> Maybe X, Y -> Maybe X) ~ > > >>>>> (Z -> Maybe X, (Z, Y) -> Maybe X, (Z, Y) -> Maybe X) ~ > > >>>>> > > >>>>> and > > >>>>> > > >>>>> OneOrBoth Z Y -> Maybe X ~ > > >>>>> (Z -> Maybe X, Y -> Maybe X, (Z, Y) -> Maybe X) > > >>>>> > > >>>>> We see that those aren't the same, they have a different number > > >>>>> of > > >>>>> elements, so, no luck. > > >>>> > > >>>> Doesn't this chain of isomorphisms require () to be the terminal > > >>>> object, or did you take () as synonym for the terminal object in > > >>>> the > > >>>> category? For example, there are several functions of the type > > >>>> Bool -> Maybe (). > > >>>> So the terminal object in Kleisli Maybe would be Void, because > > >>>> Maybe > > >>>> Void ~ (). We'd need to make fields in OneOrBoth strict to have an > > >>>> isomorphism OneOrBoth Void a ~ a, just as the true categorical > > >>>> product > > >>>> in (->) is the strict pair. > > >>>> > > >>>> Olaf > > >>>> > > >>>>>> On 9 Jan 2021, at 22:01, Olaf Klinke > > >>>>>> wrote: > > >>>>>> > > >>>>>>> Hello! > > >>>>>>> > > >>>>>>> Finite maps from `"containers" Data.Map` look like they may > > >>>>>>> form > > >>>>>>> a > > >>>>>>> Cartesian closed category. So it makes sense to ask if the > > >>>>>>> rule > > >>>>>>> _α ⇸ > > >>>>>>> (β ⇸ γ) ≡ ⟨α; β⟩ ⇸ γ ≡ ⟨β; α⟩ ⇸ γ ≡ β ⇸ (α ⇸ γ)_ that holds > > >>>>>>> in > > >>>>>>> such > > >>>>>>> categories does hold for finite maps. Note that, a map being > > >>>>>>> a > > >>>>>>> functor, this also may be seen as _f (g α) ≡ g (f α)_, which > > >>>>>>> would > > >>>>>>> work if maps were `Distributive` [1]. > > >>>>>>> > > >>>>>>> It looks to me as though the following definition might work: > > >>>>>>> > > >>>>>>> distribute = unionsWith union . mapWithKey (fmap . > > >>>>>>> singleton) > > >>>>>>> > > >>>>>>> — And it works on simple examples. _(I checked the law > > >>>>>>> `distribute ∘ > > >>>>>>> distribute ≡ id` — it appears to be the only law required.)_ > > >>>>>>> > > >>>>>>> Is this definition correct? Is it already known and defined > > >>>>>>> elsewhere? > > >>>>>>> > > >>>>>>> [1]: > > >>>>>>> > > >>>> > > >> > > https://hackage.haskell.org/package/distributive-0.6.2.1/docs/Data-Distributive.html#t:Distributive > > >>>>>> Hi Ignat, > > >>>>>> > > >>>>>> TL;DR: No and no. > > >>>>>> > > >>>>>> The documentation says that every distributive functor is of > > >>>>>> the > > >>>>>> form > > >>>>>> (->) x for some x, and (Map a) is not like this. > > >>>>>> > > >>>>>> If Maps were a category, what is the identity morphism? > > >>>>>> > > >>>>>> Let's put the Ord constraint on the keys aside, Tom Smeding has > > >>>>>> already > > >>>>>> commented on that. Next, a Map is always finite, hence let's > > >>>>>> pretend > > >>>>>> that we are working inside the category of finite types and > > >>>>>> functions. > > >>>>>> Then the problems of missing identity and missing Ord go away. > > >>>>>> Once > > >>>>>> that all types are finite, we can assume an enumerator. That > > >>>>>> is, > > >>>>>> each > > >>>>>> type x has an operation > > >>>>>> enumerate :: [x] > > >>>>>> which we will use to construct the inverse of > > >>>>>> flip Map.lookup :: Map a b -> a -> Maybe b > > >>>>>> thereby showing that a Map is nothing but a memoized version of > > >>>>>> a > > >>>>>> Kleisli map (a -> Maybe b). Convince yourself that Map > > >>>>>> concatenation > > >>>>>> has the same semantics as Kleisli composition (<=<). Given a > > >>>>>> Kleisli > > >>>>>> map k between finite types, we build a Map as follows. > > >>>>>> \k -> Map.fromList (enumerate >>= (\a -> maybe [] (pure.(,) a) > > >>>>>> (k > > >>>>>> a))) > > >>>>>> > > >>>>>> With that knowledge, we can answer your question by deciding: > > >>>>>> Is > > >>>>>> the > > >>>>>> Kleisli category of the Maybe monad on finite types Cartesian > > >>>>>> closed? > > >>>>>> Short answer: It is not even Cartesian. > > >>>>>> There is an adjunction between the categories (->) and (Kleisli > > >>>>>> m) > > >>>>>> for > > >>>>>> every monad m, where > > >>>>>> * The left adjoint functor takes > > >>>>>> types x to x, > > >>>>>> functions f to return.f > > >>>>>> * The right adjoint functor takes > > >>>>>> types x to m x, > > >>>>>> Kleisli maps f to (=<<) f > > >>>>>> Right adjoint functors preserve all existing limits, which > > >>>>>> includes > > >>>>>> products. Therefore, if (Kleisli m) has binary products, then m > > >>>>>> must > > >>>>>> preserve them. So if P x y was the product of x and y in > > >>>>>> Kleisli m, > > >>>>>> then m (P x y) would be isomorphic to (m x,m y). This seems not > > >>>>>> to > > >>>>>> hold > > >>>>>> for m = Maybe: I can not imagine a type constructor P where > > >>>>>> Maybe (P x y) ~ (Maybe x,Maybe y). > > >>>>>> In particular, P can not be (,). The only sensible Kleisli > > >>>>>> projections > > >>>>>> from (x,y) would be fst' = return.fst and snd' = return.snd. > > >>>>>> Now > > >>>>>> think > > >>>>>> of two Kleisli maps f :: Bool -> Maybe x, g :: Bool -> Maybe y. > > >>>>>> Assume > > >>>>>> that f True = Just x for some x and g True = Nothing. In order > > >>>>>> to > > >>>>>> satisfy g True = (snd' <=< (f&&&g))True, the unique pair arrow > > >>>>>> (f&&&g) > > >>>>>> would need to map True to Nothing, but then f True = (fst' <=< > > >>>>>> (f&&&g)) > > >>>>>> True can not hold. We conclude that (Kleisli Maybe) does not > > >>>>>> even > > >>>>>> have > > >>>>>> categorical products, so asking for Cartesian closure does not > > >>>>>> make > > >>>>>> sense. > > >>>>>> > > >>>>>> You might ask for a weaker property: For every type x, ((,) x) > > >>>>>> is a > > >>>>>> functor on (Kleisli Maybe). Indeed, the following works because > > >>>>>> ((,) x) > > >>>>>> is a polynomial functor. > > >>>>>> fmapKleisli :: Functor m => (a -> m b) -> (x,a) -> m (x,b) > > >>>>>> fmapKleisli f (x,a) = fmap ((,) x) (f a) > > >>>>>> Thus you may ask whether this functor has a right adjoint in > > >>>>>> the > > >>>>>> Kleisli category of Maybe. This would be a type constructor g > > >>>>>> with > > >>>>>> a > > >>>>>> natural isomorphism > > >>>>>> > > >>>>>> (x,a) -> Maybe b ~ a -> Maybe (g b). > > >>>>>> > > >>>>>> The first thing that comes to mind is to try > > >>>>>> g b = x -> Maybe b and indeed djinn can provide two functions > > >>>>>> going > > >>>>>> back and forth that have the right type, but they do not > > >>>>>> establish > > >>>>>> an > > >>>>>> isomorphism. I doubt there is such a right adjoint g, but can > > >>>>>> not > > >>>>>> prove > > >>>>>> it at the moment. The idea is that a function (x,a) -> Maybe b > > >>>>>> may > > >>>>>> decide for Nothing depending on both x and a, and therefore the > > >>>>>> image > > >>>>>> function under the isomorphism must map every a to Just (g b) > > >>>>>> and > > >>>>>> delay > > >>>>>> the Nothing-decision to the g b. But for the reverse > > >>>>>> isomorphism > > >>>>>> you > > >>>>>> can have functions that do not always return Just (g b) and > > >>>>>> there > > >>>>>> is no > > >>>>>> preimage for these. From olf at aatal-apotheke.de Sun Jan 10 14:25:55 2021 From: olf at aatal-apotheke.de (Olaf Klinke) Date: Sun, 10 Jan 2021 15:25:55 +0100 Subject: [Haskell-cafe] A quick question about distribution of finite maps. In-Reply-To: References: <7746ffa9ced97f507e095f4e8477d6b5acf2bd78.camel@aatal-apotheke.de> <651e7eb0f0f75978fa58dc6194fe572b61f4a668.camel@aatal-apotheke.de> Message-ID: <95edc34811cb3acc02cc551f35f39a35301fd185.camel@aatal-apotheke.de> On Sun, 2021-01-10 at 07:54 +0000, jack at jackkelly.name wrote: > You may be thinking of https://hackage.haskell.org/package/smash and > related packages. > > -- Jack Excellent, thanks for the hint! I shall also keep an eye on Emily's packages in addition to Edward Kmett's when looking for category- related stuff. The documentation mentions that Can is the categorical product in Hask*. Unfortunately it does not say what the morphisms in Hask* are. The linked ncatlab page suggests the morphisms are point- preserving functions, which would fit Kleisli Maybe. The documentation of Data.Can also does not state whether canCurry and canUncurry are mutually inverse. If so, that still does not contradict MigMit because the first argument to canCurry might not preserve the point, i.e. might not be a morphism of Hask*. Likewise, if the first argument k to canUncurry has k Nothing Nothing = Just _ then canUncurry k does not preserve the point, i.e. is not an element of Hask*. Anyways, we have Maybe (OneOrBoth x y) ~ Maybe (These x y) ~ Can x y with iso1 = can (\x -> (Just x,Nothing)) (\y -> (Nothing,Just y)) (\x y -> (Just x,Just y)) but still no mention of an inverse. Or am I missing something? How to constuct iso2 and pairKleisli using the combinators in Data.Can? Olaf > > January 10, 2021 5:19 PM, "David Feuer" > wrote: > > > I just don't want to take credit for anyone else's work. Neither do I, hence I mentioned you in my code. > > I have a very vague recollection that > > Emily Pillmore may have looked at some related categorical stuff, > > but I could easily be mistaken. > > > > On Sun, Jan 10, 2021, 2:16 AM Olaf Klinke > > wrote: > > > > > On Sat, 2021-01-09 at 18:04 -0500, David Feuer wrote: > > > > `These` is not my own invention. It's in the `these` package. > > > > > > Then please interpret my "due to David Feuer" as "brought into > > > this > > > discussion by David Feuer". I wonder whether These has ever been > > > linked > > > to categorical products in Kleisli Maybe before. There are > > > Data.These.Combinators.justHere and justThere which are the same > > > as my > > > fstMaybe and sndMaybe. But combinators resulting in pairKleisli > > > and > > > iso1 seem to be missing from the these package. > > > > > > Olaf > > > > > > > On Sat, Jan 9, 2021, 5:41 PM Olaf Klinke > > > > > > > > wrote: > > > > > > > > > On Sat, 2021-01-09 at 22:26 +0100, MigMit wrote: > > > > > > Actually, it's pretty easy to construct a type `P x y`, so > > > > > > that > > > > > > Maybe > > > > > > (P x y) ~ (Maybe x, Maybe y). It would be > > > > > > > > > > > > data OneOrBoth x y = Left' x | Right' y | Both x y > > > > > > > > > > > > The isomorphism is, I think, obvious > > > > > > > > > > > > iso1 :: Maybe (OneOrBoth x y) -> (Maybe x, Maybe y) > > > > > > iso1 Nothing = (Nothing, Nothing) > > > > > > iso1 (Just (Left' x)) = (Just x, Nothing) > > > > > > iso1 (Just (Right' y)) = (Nothing, Just y) > > > > > > iso1 (Just (Both x y)) = (Just x, Just y) > > > > > > > > > > > > iso2 :: (Maybe x, Maybe y) -> Maybe (OneOrBoth x y) > > > > > > iso2 = -- left as an excersize for the reader > > > > > > > > > > > > And indeed, "OneOrBoth" would be a cartesian product > > > > > > functor in > > > > > > the > > > > > > category of finite types (and maps). > > > > > > > > > > I stand corrected. Below is the full code, in case anyone > > > > > wants to > > > > > play > > > > > with it. > > > > > > > > > > import Control.Arrow ((&&&)) > > > > > > > > > > -- due to David Feuer > > > > > data OneOrBoth x y = Left' x | Right' y | Both x y > > > > > > > > > > iso2 :: (Maybe x,Maybe y) -> Maybe (OneOrBoth x y) > > > > > iso2 p = case p of > > > > > (Nothing,Nothing) -> Nothing > > > > > (Just x,Nothing) -> (Just (Left' x)) > > > > > (Nothing,Just y) -> (Just (Right' y)) > > > > > (Just x, Just y) -> (Just (Both x y)) > > > > > > > > > > -- (OneOrBoth x) is a functor on Kleisli Maybe > > > > > fmapKleisli :: (a -> Maybe b) -> > > > > > OneOrBoth x a -> Maybe (OneOrBoth x b) > > > > > fmapKleisli k (Left' x) = Just (Left' x) > > > > > fmapKleisli k (Right' a) = fmap Right' (k a) > > > > > fmapKleisli k (Both x a) = fmap (Both x) (k a) > > > > > > > > > > -- is OneOrBoth the cartesian product? Seems so: > > > > > > > > > > pairKleisli :: (a -> Maybe x) -> > > > > > (a -> Maybe y) -> > > > > > a -> Maybe (OneOrBoth x y) > > > > > pairKleisli f g = iso2 . (f &&& g) > > > > > > > > > > fstMaybe :: OneOrBoth x y -> Maybe x > > > > > fstMaybe (Left' x) = Just x > > > > > fstMaybe (Both x _) = Just x > > > > > fstMaybe (Right' _) = Nothing > > > > > > > > > > sndMaybe :: OneOrBoth x y -> Maybe y > > > > > sndMaybe (Left' _) = Nothing > > > > > sndMaybe (Right' y) = Just y > > > > > sndMaybe (Both _ y) = Just y > > > > > > > > > > > But it won't be cartesian closed. If it were, then for any > > > > > > finite > > > > > > X > > > > > > and Y we should have > > > > > > > > > > > > Maybe (X^Y) ~ > > > > > > () -> Maybe (X^Y) ~ > > > > > > OneOrBoth () Y -> Maybe X ~ > > > > > > (() -> Maybe X, Y -> Maybe X, ((), Y) -> Maybe X) ~ > > > > > > (Maybe X, Y -> Maybe X, Y -> Maybe X) > > > > > > > > > > > > so > > > > > > > > > > > > X^Y ~ (X, Y -> Maybe X, Y -> Maybe X) > > > > > > > > > > > > But then > > > > > > > > > > > > Z -> Maybe (X^Y) ~ > > > > > > Z -> (Maybe X, Y -> Maybe X, Y -> Maybe X) ~ > > > > > > (Z -> Maybe X, (Z, Y) -> Maybe X, (Z, Y) -> Maybe X) ~ > > > > > > > > > > > > and > > > > > > > > > > > > OneOrBoth Z Y -> Maybe X ~ > > > > > > (Z -> Maybe X, Y -> Maybe X, (Z, Y) -> Maybe X) > > > > > > > > > > > > We see that those aren't the same, they have a different > > > > > > number > > > > > > of > > > > > > elements, so, no luck. > > > > > > > > > > Doesn't this chain of isomorphisms require () to be the > > > > > terminal > > > > > object, or did you take () as synonym for the terminal object > > > > > in > > > > > the > > > > > category? For example, there are several functions of the > > > > > type > > > > > Bool -> Maybe (). > > > > > So the terminal object in Kleisli Maybe would be Void, > > > > > because > > > > > Maybe > > > > > Void ~ (). We'd need to make fields in OneOrBoth strict to > > > > > have an > > > > > isomorphism OneOrBoth Void a ~ a, just as the true > > > > > categorical > > > > > product > > > > > in (->) is the strict pair. > > > > > > > > > > Olaf > > > > > > > > > > > > On 9 Jan 2021, at 22:01, Olaf Klinke < > > > > > > > olf at aatal-apotheke.de> > > > > > > > wrote: > > > > > > > > > > > > > > > Hello! > > > > > > > > > > > > > > > > Finite maps from `"containers" Data.Map` look like they > > > > > > > > may > > > > > > > > form > > > > > > > > a > > > > > > > > Cartesian closed category. So it makes sense to ask if > > > > > > > > the > > > > > > > > rule > > > > > > > > _α ⇸ > > > > > > > > (β ⇸ γ) ≡ ⟨α; β⟩ ⇸ γ ≡ ⟨β; α⟩ ⇸ γ ≡ β ⇸ (α ⇸ γ)_ that > > > > > > > > holds > > > > > > > > in > > > > > > > > such > > > > > > > > categories does hold for finite maps. Note that, a map > > > > > > > > being > > > > > > > > a > > > > > > > > functor, this also may be seen as _f (g α) ≡ g (f α)_, > > > > > > > > which > > > > > > > > would > > > > > > > > work if maps were `Distributive` [1]. > > > > > > > > > > > > > > > > It looks to me as though the following definition might > > > > > > > > work: > > > > > > > > > > > > > > > > distribute = unionsWith union . mapWithKey (fmap . > > > > > > > > singleton) > > > > > > > > > > > > > > > > — And it works on simple examples. _(I checked the law > > > > > > > > `distribute ∘ > > > > > > > > distribute ≡ id` — it appears to be the only law > > > > > > > > required.)_ > > > > > > > > > > > > > > > > Is this definition correct? Is it already known and > > > > > > > > defined > > > > > > > > elsewhere? > > > > > > > > > > > > > > > > [1]: > > > > > > > > > > > https://hackage.haskell.org/package/distributive-0.6.2.1/docs/Data-Distributive.html#t:Distributive > > > > > > > Hi Ignat, > > > > > > > > > > > > > > TL;DR: No and no. > > > > > > > > > > > > > > The documentation says that every distributive functor is > > > > > > > of > > > > > > > the > > > > > > > form > > > > > > > (->) x for some x, and (Map a) is not like this. > > > > > > > > > > > > > > If Maps were a category, what is the identity morphism? > > > > > > > > > > > > > > Let's put the Ord constraint on the keys aside, Tom > > > > > > > Smeding has > > > > > > > already > > > > > > > commented on that. Next, a Map is always finite, hence > > > > > > > let's > > > > > > > pretend > > > > > > > that we are working inside the category of finite types > > > > > > > and > > > > > > > functions. > > > > > > > Then the problems of missing identity and missing Ord go > > > > > > > away. > > > > > > > Once > > > > > > > that all types are finite, we can assume an enumerator. > > > > > > > That > > > > > > > is, > > > > > > > each > > > > > > > type x has an operation > > > > > > > enumerate :: [x] > > > > > > > which we will use to construct the inverse of > > > > > > > flip Map.lookup :: Map a b -> a -> Maybe b > > > > > > > thereby showing that a Map is nothing but a memoized > > > > > > > version of > > > > > > > a > > > > > > > Kleisli map (a -> Maybe b). Convince yourself that Map > > > > > > > concatenation > > > > > > > has the same semantics as Kleisli composition (<=<). > > > > > > > Given a > > > > > > > Kleisli > > > > > > > map k between finite types, we build a Map as follows. > > > > > > > \k -> Map.fromList (enumerate >>= (\a -> maybe [] > > > > > > > (pure.(,) a) > > > > > > > (k > > > > > > > a))) > > > > > > > > > > > > > > With that knowledge, we can answer your question by > > > > > > > deciding: > > > > > > > Is > > > > > > > the > > > > > > > Kleisli category of the Maybe monad on finite types > > > > > > > Cartesian > > > > > > > closed? > > > > > > > Short answer: It is not even Cartesian. > > > > > > > There is an adjunction between the categories (->) and > > > > > > > (Kleisli > > > > > > > m) > > > > > > > for > > > > > > > every monad m, where > > > > > > > * The left adjoint functor takes > > > > > > > types x to x, > > > > > > > functions f to return.f > > > > > > > * The right adjoint functor takes > > > > > > > types x to m x, > > > > > > > Kleisli maps f to (=<<) f > > > > > > > Right adjoint functors preserve all existing limits, > > > > > > > which > > > > > > > includes > > > > > > > products. Therefore, if (Kleisli m) has binary products, > > > > > > > then m > > > > > > > must > > > > > > > preserve them. So if P x y was the product of x and y in > > > > > > > Kleisli m, > > > > > > > then m (P x y) would be isomorphic to (m x,m y). This > > > > > > > seems not > > > > > > > to > > > > > > > hold > > > > > > > for m = Maybe: I can not imagine a type constructor P > > > > > > > where > > > > > > > Maybe (P x y) ~ (Maybe x,Maybe y). > > > > > > > In particular, P can not be (,). The only sensible > > > > > > > Kleisli > > > > > > > projections > > > > > > > from (x,y) would be fst' = return.fst and snd' = > > > > > > > return.snd. > > > > > > > Now > > > > > > > think > > > > > > > of two Kleisli maps f :: Bool -> Maybe x, g :: Bool -> > > > > > > > Maybe y. > > > > > > > Assume > > > > > > > that f True = Just x for some x and g True = Nothing. In > > > > > > > order > > > > > > > to > > > > > > > satisfy g True = (snd' <=< (f&&&g))True, the unique pair > > > > > > > arrow > > > > > > > (f&&&g) > > > > > > > would need to map True to Nothing, but then f True = > > > > > > > (fst' <=< > > > > > > > (f&&&g)) > > > > > > > True can not hold. We conclude that (Kleisli Maybe) does > > > > > > > not > > > > > > > even > > > > > > > have > > > > > > > categorical products, so asking for Cartesian closure > > > > > > > does not > > > > > > > make > > > > > > > sense. > > > > > > > > > > > > > > You might ask for a weaker property: For every type x, > > > > > > > ((,) x) > > > > > > > is a > > > > > > > functor on (Kleisli Maybe). Indeed, the following works > > > > > > > because > > > > > > > ((,) x) > > > > > > > is a polynomial functor. > > > > > > > fmapKleisli :: Functor m => (a -> m b) -> (x,a) -> m > > > > > > > (x,b) > > > > > > > fmapKleisli f (x,a) = fmap ((,) x) (f a) > > > > > > > Thus you may ask whether this functor has a right adjoint > > > > > > > in > > > > > > > the > > > > > > > Kleisli category of Maybe. This would be a type > > > > > > > constructor g > > > > > > > with > > > > > > > a > > > > > > > natural isomorphism > > > > > > > > > > > > > > (x,a) -> Maybe b ~ a -> Maybe (g b). > > > > > > > > > > > > > > The first thing that comes to mind is to try > > > > > > > g b = x -> Maybe b and indeed djinn can provide two > > > > > > > functions > > > > > > > going > > > > > > > back and forth that have the right type, but they do not > > > > > > > establish > > > > > > > an > > > > > > > isomorphism. I doubt there is such a right adjoint g, but > > > > > > > can > > > > > > > not > > > > > > > prove > > > > > > > it at the moment. The idea is that a function (x,a) -> > > > > > > > Maybe b > > > > > > > may > > > > > > > decide for Nothing depending on both x and a, and > > > > > > > therefore the > > > > > > > image > > > > > > > function under the isomorphism must map every a to Just > > > > > > > (g b) > > > > > > > and > > > > > > > delay > > > > > > > the Nothing-decision to the g b. But for the reverse > > > > > > > isomorphism > > > > > > > you > > > > > > > can have functions that do not always return Just (g b) > > > > > > > and > > > > > > > there > > > > > > > is no > > > > > > > preimage for these. > > > > > > > > > > > > > > Regards, > > > > > > > Olaf > > > > > > > > > > > > > > > > > > > > > > > > > > > > _______________________________________________ > > > > > > > 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 viercc at gmail.com Sun Jan 10 18:11:44 2021 From: viercc at gmail.com (=?UTF-8?B?5a6u6YeM5rS45Y+4?=) Date: Mon, 11 Jan 2021 03:11:44 +0900 Subject: [Haskell-cafe] A quick question about distribution of finite maps. In-Reply-To: References: <87v9c6b97x.fsf@hyperspace> Message-ID: > I take **Finite Set** to be Cartesian closed with the same product and exponent > objects as its supercategory **Set**. Objections? No objections! I wanted to stress that it's always beneficial to start from "obvious" definitions. Maybe it's tedious, but too long is better than too vague for readers. Also, there can't be objections! You're the one to define. Of course I could've speculated whatever definitions, but they're not necessarily related to what you wanted to know. > Particularly, I do not invoke the `Maybe` stuff — instead I say that an > evaluation of a finite map on a value outside the set of its keys is an error > and it is the responsibility of the programmer to prove that no such evaluations > occur, even though they may pass the type checker. Yes, I give up type safety. So here was where the miscommunication happened. I think people replying, including me, were assuming you're thinking in terms of composing maps as concrete version of Kleisli arrows `a -> Maybe b`. > ## Now to the technical details. Thank you for details, I can get to write on the meat of the question. Hope it helps! Before starting, to be extra sure, let me restate we suppose `Map a b` are the representation of *total* functions between finite subsets of `a` and `b`, where these subsets are implicitly assumed. The failing example can be seen as the result of the "implicitly assumed" part not working well. distribute :: (Ord a, Ord b) => Map a (Map b x) -> Map b (Map a x) distribute = Map.unionsWith Map.union . Map.mapWithKey (fmap . Map.singleton) m :: Map Int (Map Int x) m = Map.fromList 1 [Map.fromList []] m' = distribute m = Map.fromList [] m'' = distribute m' {- should be equal to m -} Let me write the "implicitly assumed" subsets, using the imaginary syntax: m :: Map {1} (Map ∅ x) m' :: Map ∅ (Map ?? x) The problem occurs here. Because the domain and the range of each map is implicit, you can lose track of the "type" in the empty map. ("type" here doesn't mean an actual type Haskell checks for you, but virtual one asserting which finite sets are the domain and range of a given Map.) The most easy (but less flexible) way to recover a nice mathematical structure will be restricting Maps to be nonempty. There's no case you lose "type" information other than it. -- /* Koji Miyazato */ From olf at aatal-apotheke.de Sun Jan 10 21:10:58 2021 From: olf at aatal-apotheke.de (Olaf Klinke) Date: Sun, 10 Jan 2021 22:10:58 +0100 Subject: [Haskell-cafe] A quick question about distribution of finite maps. In-Reply-To: References: <7746ffa9ced97f507e095f4e8477d6b5acf2bd78.camel@aatal-apotheke.de> Message-ID: <2fb381908219363cf217162000ef442cc90263a3.camel@aatal-apotheke.de> On Sat, 2021-01-09 at 23:45 +0100, MigMit wrote: But it won't be cartesian closed. If it were, then for any finite > > > X > > > and Y we should have > > > > > > Maybe (X^Y) ~ > > > () -> Maybe (X^Y) ~ > > > OneOrBoth () Y -> Maybe X ~ > > > (() -> Maybe X, Y -> Maybe X, ((), Y) -> Maybe X) ~ > > > (Maybe X, Y -> Maybe X, Y -> Maybe X) > > > > > > so > > > > > > X^Y ~ (X, Y -> Maybe X, Y -> Maybe X) > > > > No, my arrows and isomorphisms are all in the original category, not > the Kleisli one — although the "X^Y" is the exponent in the Kleisli > category. I don't follow your argument. I still must be misinterpreting something. Maybe (X^Y) ~ () -> Maybe (X^Y) -- because () is terminal in Hask ~ OneOrBoth () Y -> Maybe X -- OneOrBoth is the product in Kleisli Maybe ~ (Maybe X, Y -> Maybe X, Y -> Maybe X) -- universal property of coproduct But how did you get to the next step: X^Y ~ (X, Y -> Maybe X, Y -> Maybe X) I think this can not hold for cardinality reasons: 1+X*((1+X)^Y)^2 /= (1+X)*((1+X)^Y)^2 Olaf From migmit at gmail.com Sun Jan 10 21:25:36 2021 From: migmit at gmail.com (MigMit) Date: Sun, 10 Jan 2021 22:25:36 +0100 Subject: [Haskell-cafe] A quick question about distribution of finite maps. In-Reply-To: <2fb381908219363cf217162000ef442cc90263a3.camel@aatal-apotheke.de> References: <7746ffa9ced97f507e095f4e8477d6b5acf2bd78.camel@aatal-apotheke.de> <2fb381908219363cf217162000ef442cc90263a3.camel@aatal-apotheke.de> Message-ID: Damn, you're right, my mistake. So, in short, there doesn't seem to be a good representation for (X^Y). But even if it was, we can be certain that #(X^Y) = (#X + 1) * (#X + 1)^(#Y) * (#X + 1)^(#Y) - 1 = (#X + 1)^(2 * #Y + 1) - 1 That makes it possible to calculate both #(Z -> Maybe X^Y) and #(OneOrBoth Z Y -> Maybe X): #(Z -> Maybe X^Y) = #(Maybe X^Y)^#Z = (#X + 1)^(2 * #Y * #Z + #Z) #(OneOrBoth Z Y -> Maybe X) = #(Maybe X)^#(OneOrBoth Z Y) = (#X + 1)^(#Y * #Z + #Y + #Z) and we still see that they are different, unless X is empty or Z ~ (). Thanks! > On 10 Jan 2021, at 22:10, Olaf Klinke wrote: > > On Sat, 2021-01-09 at 23:45 +0100, MigMit wrote: > But it won't be cartesian closed. If it were, then for any finite >>>> X >>>> and Y we should have >>>> >>>> Maybe (X^Y) ~ >>>> () -> Maybe (X^Y) ~ >>>> OneOrBoth () Y -> Maybe X ~ >>>> (() -> Maybe X, Y -> Maybe X, ((), Y) -> Maybe X) ~ >>>> (Maybe X, Y -> Maybe X, Y -> Maybe X) >>>> >>>> so >>>> >>>> X^Y ~ (X, Y -> Maybe X, Y -> Maybe X) >>>> >> No, my arrows and isomorphisms are all in the original category, not >> the Kleisli one — although the "X^Y" is the exponent in the Kleisli >> category. > > I don't follow your argument. I still must be misinterpreting > something. > > Maybe (X^Y) > ~ () -> Maybe (X^Y) > -- because () is terminal in Hask > ~ OneOrBoth () Y -> Maybe X > -- OneOrBoth is the product in Kleisli Maybe > ~ (Maybe X, Y -> Maybe X, Y -> Maybe X) > -- universal property of coproduct > > But how did you get to the next step: > > X^Y ~ (X, Y -> Maybe X, Y -> Maybe X) > > I think this can not hold for cardinality reasons: > > 1+X*((1+X)^Y)^2 /= (1+X)*((1+X)^Y)^2 > > Olaf > From stefan.wehr at gmail.com Mon Jan 11 16:49:04 2021 From: stefan.wehr at gmail.com (Stefan Wehr) Date: Mon, 11 Jan 2021 17:49:04 +0100 Subject: [Haskell-cafe] 2nd Call for Participation: BOB 2021 (February 26, online) Message-ID: ================================================================================ BOB 2021 Conference “What happens if we simply use what’s best?” February 26, 2021, online (UTC+0100) http://bobkonf.de/2021/ Program: http://bobkonf.de/2021/program.html Registration: http://bobkonf.de/2021/registration.html ================================================================================ BOB conference is a place for developers, architects and decision-makers to explore technologies beyond the mainstream in software development, and to find the best tools available to software developers today. Our goal is for all participants of BOB to return home with new insights that enable them to improve their own software development experience. The program features 14 talks and 8 tutorials on current topics: http://bobkonf.de/2021/program.html The subject range includes functional programming, logic programming, revision control, formal methods, mindfulness, event sourcing, front-end development, and more. Jeremy Gibbons will give the keynote talk. BOB 2021 will take place online. We are working towards fostering lively exchange of exciting ideas and enable meaningful social interactions. Registration is open online: http://bobkonf.de/2021/registration.html Registration is €30 for a regular ticket, €15 for a student ticket. (If you need financial aid, let us know.) We intend to make this the most diverse, colorful, fun BOB ever! -------------- next part -------------- An HTML attachment was scrubbed... URL: From olf at aatal-apotheke.de Mon Jan 11 21:52:49 2021 From: olf at aatal-apotheke.de (Olaf Klinke) Date: Mon, 11 Jan 2021 22:52:49 +0100 Subject: [Haskell-cafe] A quick question about distribution of finite maps. Message-ID: > I find the idea that finite sets and functions may be > represented in Haskell very attractive in general Okay, so the Map was a red herring. It is only one possible implementation of the mathematical concept you are after. To be more clear, let's use Map with capital M whenever we mean the data structure and "map" or "function" whenever we mean the mathematical concept. What you really want is functions between finite sets. Maps do not, in general, represent functions in the Control.Category sense. That got me hooked onto the Kleisli thing. Classical case of nerd-sniping. But you want to deviate from Control.Category and that's perfectly fine because we know the math works. > This establishes a Cartesian closed category of somewhat idealized > entities. Can > the realization of this category in Haskell be perfected to exclude > pathologies > by construction? I think you need dependent types, but let's try. import Data.Map (Map) import qualified Data.Map.Strict as Map import Data.Set (Set) import qualified Data.Set as Set -- Note: One could also define -- FiniteFunction a b = (Set a, a -> b) -- hence the Map in your OP was misleading. newtype FiniteFunction a b = FMap {asMap :: Map a b} domain :: FiniteFunction a b -> Set a domain = Map.keysSet . asMap codomain :: Ord b => FiniteFunction a b -> Set b codomain = Set.fromList . Map.elems . asMap unsafeRunFiniteFunction :: Ord a => FiniteFunction a b -> a -> b unsafeRunFiniteFunction = (assertDomain.) . flip Map.lookup . asMap where assertDomain (Just b) = b assertDomain Nothing = error "argument outside of domain" -- | @(unsafeRunFiniteFunction f) `restrictedTo` (domain f) = f@ restrictedTo :: (a -> b) -> Set a -> FiniteFunction a b f `restrictedTo` dom = FMap (Map.fromSet f dom) -- | (.) of the category. -- 'id' on dom is @id `restrictedTo` dom@ compose :: (Ord a, Ord b, Ord c) => FiniteFunction b c -> FiniteFunction a b -> FiniteFunction a c compose (FMap g) (FMap f) = FMap (fmap g' f) where g' b = case Map.lookup b g of Nothing -> error "type mismatch between domain and codomain" Just c -> c {-- Now to the CCC structure. At this point we run into a problem: Categorically, if f :: A -> (C^B) and we uncurry it, then the domain of (uncurry f) is a square, the cartesian product of A and B. Trying to curry a function whose domain is a proper subset of the cartesian product of A and B should be a type error in my opinion, but Haskell's type system can not express this. I imagine failure of this property may lead to unexpected results when used in conjunction with 'compose'. But maybe currying functions with non-square domain is a desirable feature. If so, remove assertUncurried below. --} -- | @'isSquare' setOfPairs = True@ iff @setOfPairs@ -- is of the form -- @Set.fromList [(a,b) | a <- setA, b <- setB]@. isSquare :: (Ord a, Ord b) => Set (a,b) -> Bool isSquare setOfPairs = let fstProj = Set.map fst setOfPairs sndProj = Set.map snd setOfPairs in all (\a -> all (\b -> (a,b) `Set.member` setOfPairs) sndProj) fstProj isUncurried :: (Ord a, Ord b) => FiniteFunction (a,b) c -> Bool isUncurried = isSquare . domain -- | Beware: we can not express in the type system that -- for all keys @a@ the 'domain' :: Set b of the value under @a@ -- is the same Set, which is a prerequisite for the CCC operation. -- Hence we can not guarantee that the resulting 'domain' 'isSquare'. uncurryFiniteFunction :: (Ord a, Ord b) => FiniteFunction a (FiniteFunction b c) -> FiniteFunction (a,b) c uncurryFiniteFunction = FMap . Map.foldMapWithKey unc . asMap where unc a (FMap bc) = Map.mapKeysMonotonic ((,) a) bc -- | likewise, if the 'domain' of the uncurried function -- fails 'isSquare' then the result is not a well-defined -- higher-order 'FiniteFunction'. curryFiniteFunction :: (Ord a, Ord b) => FiniteFunction (a,b) c -> FiniteFunction a (FiniteFunction b c) curryFiniteFunction f@(FMap ab_c) = assertUncurried (FMap a_bc) where filterFst a = Map.foldMapWithKey (\ab c -> if fst ab == a then Map.singleton (snd ab) c else Map.empty) ab_c as = Map.foldMapWithKey (\(a,_) _ -> Set.singleton a) ab_c a_bc = Map.fromSet (FMap . filterFst) as assertUncurried = if isUncurried f then id else error "not an uncurried function" -------------- next part -------------- A non-text attachment was scrubbed... Name: FiniteFunctions.hs Type: text/x-haskell Size: 2739 bytes Desc: not available URL: From ietf-dane at dukhovni.org Tue Jan 19 17:29:13 2021 From: ietf-dane at dukhovni.org (Viktor Dukhovni) Date: Tue, 19 Jan 2021 15:29:13 -0200 Subject: [Haskell-cafe] Bind the GAP barely legible? Message-ID: <3B5DD52B-FAF7-403A-AE14-330794AB66AA@dukhovni.org> I tried to read "Bind the GAP": https://bindthegap.news/issues.html but the colours, fonts, and layout are so disorienting that I'm afraid it is just too much work to make much sense of it. Am I just too old-fashioned in my expectations, or do others alos find that the festive artwork completely overwhelms the content in this publication? If there's anyone on this list who's involved in producing the publication, please consider drastically dialing back the decorations. -- Viktor. From albert+haskell at zeitkraut.de Tue Jan 19 18:51:19 2021 From: albert+haskell at zeitkraut.de (Albert Krewinkel) Date: Tue, 19 Jan 2021 19:51:19 +0100 Subject: [Haskell-cafe] Bind the GAP barely legible? In-Reply-To: <3B5DD52B-FAF7-403A-AE14-330794AB66AA@dukhovni.org> References: <3B5DD52B-FAF7-403A-AE14-330794AB66AA@dukhovni.org> Message-ID: <87eeigdal4.fsf@zeitkraut.de> I don't think I quite understand the purpose of sending this message. BtG is not a community project, the contact info of the authors is very easy to find, and it is far too easy to interpret the mail as an opinionated rant about design choices. If you are interested in changing their concept (which, personally, I'd be sad to see happening), why not contact the authors? Viktor Dukhovni writes: > I tried to read "Bind the GAP": > > https://bindthegap.news/issues.html > > but the colours, fonts, and layout are so disorienting that > I'm afraid it is just too much work to make much sense of it. > > Am I just too old-fashioned in my expectations, or do others > alos find that the festive artwork completely overwhelms the > content in this publication? > > If there's anyone on this list who's involved in producing > the publication, please consider drastically dialing back > the decorations. -- Albert Krewinkel GPG: 8eed e3e2 e8c5 6f18 81fe e836 388d c0b2 1f63 1124 From rae at richarde.dev Tue Jan 19 18:52:58 2021 From: rae at richarde.dev (Richard Eisenberg) Date: Tue, 19 Jan 2021 18:52:58 +0000 Subject: [Haskell-cafe] Bind the GAP barely legible? In-Reply-To: <3B5DD52B-FAF7-403A-AE14-330794AB66AA@dukhovni.org> References: <3B5DD52B-FAF7-403A-AE14-330794AB66AA@dukhovni.org> Message-ID: <010f01771bfe2af0-153d796f-b26b-4479-86fe-36003e11ff70-000000@us-east-2.amazonses.com> The authors, Dmitrii Kovanikov and Veronika Romashkina, are listed prominently on the bindthegap.news website. It might be more effective to contact them directly -- and perhaps kindly offer to help edit and review their free publication -- than to complain generally and in public. Given the amount of "old-fashioned"-styled Haskell content out there already, perhaps having some with a different look will appeal to new audiences, which is surely good for all of us. Richard > On Jan 19, 2021, at 12:29 PM, Viktor Dukhovni wrote: > > I tried to read "Bind the GAP": > > https://bindthegap.news/issues.html > > but the colours, fonts, and layout are so disorienting that > I'm afraid it is just too much work to make much sense of it. > > Am I just too old-fashioned in my expectations, or do others > alos find that the festive artwork completely overwhelms the > content in this publication? > > If there's anyone on this list who's involved in producing > the publication, please consider drastically dialing back > the decorations. > > -- > Viktor. > > _______________________________________________ > 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 ietf-dane at dukhovni.org Tue Jan 19 18:55:56 2021 From: ietf-dane at dukhovni.org (Viktor Dukhovni) Date: Tue, 19 Jan 2021 16:55:56 -0200 Subject: [Haskell-cafe] Bind the GAP barely legible? In-Reply-To: <87eeigdal4.fsf@zeitkraut.de> References: <3B5DD52B-FAF7-403A-AE14-330794AB66AA@dukhovni.org> <87eeigdal4.fsf@zeitkraut.de> Message-ID: > On Jan 19, 2021, at 4:51 PM, Albert Krewinkel wrote: > > I don't think I quite understand the purpose of sending this > message. BtG is not a community project, the contact info of the > authors is very easy to find, and it is far too easy to interpret > the mail as an opinionated rant about design choices. > > If you are interested in changing their concept (which, > personally, I'd be sad to see happening), why not contact the > authors? Well, as stated, I was wondering whether in fact it was just me, or whether perhaps others potentially interested in reading the content were deterred by the design. Perhaps there's indeed an audience for the chosen design... -- Viktor. From jerzy.karczmarczuk at unicaen.fr Tue Jan 19 19:31:04 2021 From: jerzy.karczmarczuk at unicaen.fr (Jerzy Karczmarczuk) Date: Tue, 19 Jan 2021 20:31:04 +0100 Subject: [Haskell-cafe] Bind the GAP barely legible? In-Reply-To: References: <3B5DD52B-FAF7-403A-AE14-330794AB66AA@dukhovni.org> <87eeigdal4.fsf@zeitkraut.de> Message-ID: <676f8102-2b6e-02d7-9f29-3d7fc59579ff@unicaen.fr> Le 19/01/2021 à 19:55, Viktor Dukhovni a écrit : > I was wondering whether in fact it was just me, or whether perhaps > others potentially interested in reading the content were deterred by > the design. Actually, I was disturbed as well. But my glasses are inadequate... 1. But I didn't react.... 2. I think that public complaining that a site design is imperfect is not efficient. 3. *But I think also that people who attack those who complain, are even worse!* 4. *And those (as myself) who complain that the authors' defenders,who criticize the critics (2), are senseless, and awful, are simply hopeless...!!* Please continue this ping-pong, we have nothing better to do. Jerzy Karczmarczuk /Caen, France. The departure place of one William the Conqueror, who didn't like some anglo-saxons, and decided to implement some polite criticism/. -- L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel antivirus Avast. https://www.avast.com/antivirus -------------- next part -------------- An HTML attachment was scrubbed... URL: From fa-ml at ariis.it Tue Jan 19 20:19:52 2021 From: fa-ml at ariis.it (Francesco Ariis) Date: Tue, 19 Jan 2021 21:19:52 +0100 Subject: [Haskell-cafe] Bind the GAP barely legible? In-Reply-To: <3B5DD52B-FAF7-403A-AE14-330794AB66AA@dukhovni.org> References: <3B5DD52B-FAF7-403A-AE14-330794AB66AA@dukhovni.org> Message-ID: <20210119201952.GA30734@extensa> Il 19 gennaio 2021 alle 15:29 Viktor Dukhovni ha scritto: > I tried to read "Bind the GAP": > > https://bindthegap.news/issues.html > > but the colours, fonts, and layout are so disorienting that > I'm afraid it is just too much work to make much sense of it. I redownloaded the issue to check: the font of the body is mostly a quite conservative, serif one. From migmit at gmail.com Tue Jan 19 20:43:30 2021 From: migmit at gmail.com (MigMit) Date: Tue, 19 Jan 2021 21:43:30 +0100 Subject: [Haskell-cafe] Bind the GAP barely legible? In-Reply-To: References: <3B5DD52B-FAF7-403A-AE14-330794AB66AA@dukhovni.org> <87eeigdal4.fsf@zeitkraut.de> Message-ID: <446E06EB-F458-45F3-9B7B-2D2AF92BBE6C@gmail.com> It's not just you; however, I have to admit I didn't know about GAP at all until you brought it up. > On 19 Jan 2021, at 19:55, Viktor Dukhovni wrote: > >> On Jan 19, 2021, at 4:51 PM, Albert Krewinkel wrote: >> >> I don't think I quite understand the purpose of sending this >> message. BtG is not a community project, the contact info of the >> authors is very easy to find, and it is far too easy to interpret >> the mail as an opinionated rant about design choices. >> >> If you are interested in changing their concept (which, >> personally, I'd be sad to see happening), why not contact the >> authors? > > Well, as stated, I was wondering whether in fact it was just me, > or whether perhaps others potentially interested in reading the > content were deterred by the design. Perhaps there's indeed an > audience for the chosen design... > > -- > Viktor. > > _______________________________________________ > 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 alan.zimm at gmail.com Tue Jan 19 20:47:38 2021 From: alan.zimm at gmail.com (Alan & Kim Zimmerman) Date: Tue, 19 Jan 2021 20:47:38 +0000 Subject: [Haskell-cafe] Time to vote on possible haskell-language-server logos Message-ID: As we announced in December last year, we are looking for a logo for the haskell language server. We now have a selection of candidates, and the voting is open [1] You can vote for as many options as you like. We are closing the poll on 26 Jan (a week from now). Make your preference known, you will hopefully be seeing it a *lot*. Alan [1] https://github.com/haskell/haskell-language-server/issues/694#issuecomment-762701777 -------------- next part -------------- An HTML attachment was scrubbed... URL: From tonyzorman at mailbox.org Tue Jan 19 21:20:23 2021 From: tonyzorman at mailbox.org (Tony Zorman) Date: Tue, 19 Jan 2021 22:20:23 +0100 Subject: [Haskell-cafe] Bind the GAP barely legible? In-Reply-To: References: <3B5DD52B-FAF7-403A-AE14-330794AB66AA@dukhovni.org> <87eeigdal4.fsf@zeitkraut.de> Message-ID: <87ft2wvd2g.fsf@hyperspace> On Tue, Jan 19 2021 16:55, Viktor Dukhovni wrote: > Well, as stated, I was wondering whether in fact it was just me, > or whether perhaps others potentially interested in reading the > content were deterred by the design. Perhaps there's indeed an > audience for the chosen design... For what it's worth, I didn't think it was very hard to read overall. Some parts—especially ones with a picture directly underneath the text—were a little bit annoying, but that only happened a few times throughout the issue. It was a very different style from what you normally read, for sure, but I found the whole concept to be absolutely delightful and distinctly remember it lifting my spirits over Christmas. I think Richard said it best in his reply: On Tue, Jan 19 2021 18:52, Richard Eisenberg wrote: > Given the amount of "old-fashioned"-styled Haskell content out there > already, perhaps having some with a different look will appeal to new > audiences, which is surely good for all of us. From jack at jackkelly.name Tue Jan 19 21:32:31 2021 From: jack at jackkelly.name (jack at jackkelly.name) Date: Tue, 19 Jan 2021 21:32:31 +0000 Subject: [Haskell-cafe] Bind the GAP barely legible? In-Reply-To: <446E06EB-F458-45F3-9B7B-2D2AF92BBE6C@gmail.com> References: <446E06EB-F458-45F3-9B7B-2D2AF92BBE6C@gmail.com> <3B5DD52B-FAF7-403A-AE14-330794AB66AA@dukhovni.org> <87eeigdal4.fsf@zeitkraut.de> Message-ID: <0d9f0538ef3a19e2d9f72c87e09e4810@jackkelly.name> The editors of BtG appear to quite deliberately take a bold step away from the "normal" design styles people use when writing about Haskell. When someone is doing something a bit different, it might be worth being a bit more careful, concrete, and kind with feedback than usual. Recall that we almost didn't have Advent of Haskell 2020: the announcements derailed into arguments about the absence of an RSS feed and the organisers nearly threw it in. In the spirit of the above, I'd suggest something like this to the authors: - I really liked the overall content. It clearly took a lot of effort to collect, they managed to organise some really great authors, and there's stuff in there for different skill levels. Congratulations. - The "fun" in the design is not _personally_ my style, and I do find it a little hard to get through. The good news is that the loudest stuff is mostly done outside and between articles, rather than inline. I like this because they get to have fun with the design, and I can read the articles. - There are a few places where the fun makes the text harder to read (Rank'n'Roll, some of the callouts in the Dependent Types article) - Some pages are difficult to read due to low contrast between text and background. Lightweight fonts can make this harder, too. (Examples: Pure Gold (p27) and Deriving All The Way (p13,14) (the body is easier to read than Pure Gold, but the lightweight song text I found tough).) Suggestions: - Select a standard font/size/weight for most article body text. - Check text vs. background colours using something like https://contrastchecker.com/ . WCAG AAA is more than just text contrast, but this is an easy and objective check. - Check the designs of callout boxes for readability. If using underlaid images, consider making them more subtle, or think about switching to solid blocks of colour with themed doodads on the edges. (Good example: p9 has easy-to-read callouts.) HTH, -- Jack January 20, 2021 6:43 AM, "MigMit" wrote: > It's not just you; however, I have to admit I didn't know about GAP at all until you brought it up. > >> On 19 Jan 2021, at 19:55, Viktor Dukhovni wrote: > > On Jan 19, 2021, at 4:51 PM, Albert Krewinkel wrote: > > I don't think I quite understand the purpose of sending this > message. BtG is not a community project, the contact info of the > authors is very easy to find, and it is far too easy to interpret > the mail as an opinionated rant about design choices. > > If you are interested in changing their concept (which, > personally, I'd be sad to see happening), why not contact the > authors? >> Well, as stated, I was wondering whether in fact it was just me, >> or whether perhaps others potentially interested in reading the >> content were deterred by the design. Perhaps there's indeed an >> audience for the chosen design... >> >> -- >> Viktor. >> >> _______________________________________________ >> 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 jm at memorici.de Wed Jan 20 00:49:10 2021 From: jm at memorici.de (Jonn Mostovoy) Date: Wed, 20 Jan 2021 00:49:10 +0000 Subject: [Haskell-cafe] Bind the GAP barely legible? In-Reply-To: <0d9f0538ef3a19e2d9f72c87e09e4810@jackkelly.name> References: <3B5DD52B-FAF7-403A-AE14-330794AB66AA@dukhovni.org> <87eeigdal4.fsf@zeitkraut.de> <446E06EB-F458-45F3-9B7B-2D2AF92BBE6C@gmail.com> <0d9f0538ef3a19e2d9f72c87e09e4810@jackkelly.name> Message-ID: I believe that it's important to chime in: 1. I support Haskell content in any form 2. I have experienced physiological response to the first issue of GAP, so I couldn't read it (headache) 3. It probably can mitigated by simply providing text source of the articles. The Internet is for text after all. — Kindest regards, ¬Σ On Tue, Jan 19, 2021 at 9:34 PM Jack Kelly via Haskell-Cafe < haskell-cafe at haskell.org> wrote: > The editors of BtG appear to quite deliberately take a bold step away from > the "normal" design styles people use when writing about Haskell. When > someone is doing something a bit different, it might be worth being a bit > more careful, concrete, and kind with feedback than usual. Recall that we > almost didn't have Advent of Haskell 2020: the announcements derailed into > arguments about the absence of an RSS feed and the organisers nearly threw > it in. > > In the spirit of the above, I'd suggest something like this to the authors: > > - I really liked the overall content. It clearly took a lot of effort to > collect, they managed to organise some really great authors, and there's > stuff in there for different skill levels. Congratulations. > - The "fun" in the design is not _personally_ my style, and I do find it a > little hard to get through. The good news is that the loudest stuff is > mostly done outside and between articles, rather than inline. I like this > because they get to have fun with the design, and I can read the articles. > - There are a few places where the fun makes the text harder to read > (Rank'n'Roll, some of the callouts in the Dependent Types article) > - Some pages are difficult to read due to low contrast between text and > background. Lightweight fonts can make this harder, too. (Examples: Pure > Gold (p27) and Deriving All The Way (p13,14) (the body is easier to read > than Pure Gold, but the lightweight song text I found tough).) > > Suggestions: > > - Select a standard font/size/weight for most article body text. > - Check text vs. background colours using something like > https://contrastchecker.com/ . WCAG AAA is more than just text contrast, > but this is an easy and objective check. > - Check the designs of callout boxes for readability. If using underlaid > images, consider making them more subtle, or think about switching to solid > blocks of colour with themed doodads on the edges. (Good example: p9 has > easy-to-read callouts.) > > HTH, > > -- Jack > > January 20, 2021 6:43 AM, "MigMit" wrote: > > > It's not just you; however, I have to admit I didn't know about GAP at > all until you brought it up. > > > >> On 19 Jan 2021, at 19:55, Viktor Dukhovni > wrote: > > > > On Jan 19, 2021, at 4:51 PM, Albert Krewinkel < > albert+haskell at zeitkraut.de> wrote: > > > > I don't think I quite understand the purpose of sending this > > message. BtG is not a community project, the contact info of the > > authors is very easy to find, and it is far too easy to interpret > > the mail as an opinionated rant about design choices. > > > > If you are interested in changing their concept (which, > > personally, I'd be sad to see happening), why not contact the > > authors? > >> Well, as stated, I was wondering whether in fact it was just me, > >> or whether perhaps others potentially interested in reading the > >> content were deterred by the design. Perhaps there's indeed an > >> audience for the chosen design... > >> > >> -- > >> Viktor. > >> > >> _______________________________________________ > >> 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 fumiexcel at gmail.com Wed Jan 20 01:13:03 2021 From: fumiexcel at gmail.com (Fumiaki Kinoshita) Date: Wed, 20 Jan 2021 10:13:03 +0900 Subject: [Haskell-cafe] Bind the GAP barely legible? In-Reply-To: <3B5DD52B-FAF7-403A-AE14-330794AB66AA@dukhovni.org> References: <3B5DD52B-FAF7-403A-AE14-330794AB66AA@dukhovni.org> Message-ID: I love their fancy style! I hope they don't get reverted to some "old-fashioned" style like the 00's (I've had enough of it) and carry on with the novelty. Rather, I think the Haskell community needs even more diverse graphic design. 2021年1月20日(水) 2:29 Viktor Dukhovni : > I tried to read "Bind the GAP": > > https://bindthegap.news/issues.html > > but the colours, fonts, and layout are so disorienting that > I'm afraid it is just too much work to make much sense of it. > > Am I just too old-fashioned in my expectations, or do others > alos find that the festive artwork completely overwhelms the > content in this publication? > > If there's anyone on this list who's involved in producing > the publication, please consider drastically dialing back > the decorations. > > -- > Viktor. > > _______________________________________________ > 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 chrisreade at mac.com Thu Jan 21 13:57:21 2021 From: chrisreade at mac.com (Chris Reade) Date: Thu, 21 Jan 2021 13:57:21 +0000 Subject: [Haskell-cafe] stack: duplicate modules in library Message-ID: I have come across a problem with haskell stack putting duplicate modules in a library. On "stack build" I get "Cabal-simple_mPHDZzAJ_3.0.1.0_ghc-8.8.4: Duplicate modules in library:..” This may have originally been caused when I changed capitalisation of a filename, but changing back did not resolve the problem. My question is how do I get rid of the library so I can rebuild? I tried "stack purge” and also removing ~/.stack with no luck (the latter causes a new ghc download on stack build, but with the same message afterwards) I know the source modules are fine because they all load in "stack ghci” Is there some other directory that stack/cabal uses for binary cache that I can safely delete? Chris From jon.fairbairn at cl.cam.ac.uk Fri Jan 22 10:23:19 2021 From: jon.fairbairn at cl.cam.ac.uk (Jon Fairbairn) Date: Fri, 22 Jan 2021 10:23:19 +0000 Subject: [Haskell-cafe] stack: duplicate modules in library References: Message-ID: Chris Reade via Haskell-Cafe writes: > I have come across a problem with haskell stack putting > duplicate modules in a library. […] > I know the source modules are fine because they all load in "stack ghci” > Is there some other directory that stack/cabal uses for > binary cache that I can safely delete? does “stack clean” not help? -- Jón Fairbairn Jon.Fairbairn at cl.cam.ac.uk http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html (updated 2014-04-05) From leah at vuxu.org Fri Jan 22 11:04:25 2021 From: leah at vuxu.org (Leah Neukirchen) Date: Fri, 22 Jan 2021 12:04:25 +0100 Subject: [Haskell-cafe] Munich Virtual Haskell Meeting, 2021-01-25 @ 19:30 Message-ID: <87mtx1cjwm.fsf@vuxu.org> Dear all, Next week, our monthly Munich Haskell Meeting will take place again on Monday, January 25 on Google Meet. For details see here: **Due to meetup limitations in Bavaria, this meeting will take place online!** For details see here: http://muenchen.haskell.bayern/dates.html A Google Meet link to join the room is provided on the page. Everybody is welcome, especially the Haskellers from Bavaria that do not usually come to our Munich meetings due to travel distance! cu, -- Leah Neukirchen https://leahneukirchen.org/ From P.Achten at cs.ru.nl Fri Jan 22 13:52:42 2021 From: P.Achten at cs.ru.nl (Peter Achten) Date: Fri, 22 Jan 2021 14:52:42 +0100 Subject: [Haskell-cafe] [Lambda Days + TFP + TFPIE 2021] call for participation Message-ID: -------------------------------------------------------------------------------               C A L L  F O R  P A R T I C I P A T I O N                            8th Lambda Days                                   +  10th International Workshop on Trends in Functional Programming in Education                                   +            22nd Symposium on Trends in Functional Programming                          16 - 19 February 2021                    https://www.lambdadays.org/lambdadays2021 ------------------------------------------------------------------------------- The programmes for Lambda Days, TFPIE, and TFP are online: - Lambda Days overall program at: https://www.lambdadays.org/lambdadays2021 - TFPIE      specific program at: https://wiki.tfpie.science.ru.nl/TFPIE2021 - TFP        specific program at: http://tfp2021.org/ (all times are in Central European Time Zone: 12.00:18.00 (CEST)) Lambda Days is a place where academia meets industry, where research and practical application collide. Once again Lambda Days joins forces with Trends in Functional Programming (TFP) and Trends in Functional Programming in Education (TFPiE) so that for four days you can be at the centre of the functional programming world. The program has a lot of interesting talks, possibilities for interaction, and a host of keynote presentations: Lambda Days keynote speakers: ----------------------------- Perdita Stevens, Pat Hannahan, Simon Peyton Jones, Andy Gordon, Philip Wadler. Trends in Functional Programming in Education keynote speakers: --------------------------------------------------------------- Francesco Cesarini, Simon Thompson, and Bartosz Milewski. Trends in Functional Programming keynote speaker: ------------------------------------------------- Zhenjiang Hu. Thanks to a generous sponsor, TFP has a limited number of free tickets for PhD, Msc, Bsc students with an interest in functional programming. To apply, send a mail to the program chair of TFP, Viktória Zsók (zsv at elte.hu) with your name, university, 2-3 lines of motivation, and a valid student card photo to get the registration code. Tickets will be delivered in the order of application. From chrisreade at mac.com Fri Jan 22 14:09:57 2021 From: chrisreade at mac.com (Chris Reade) Date: Fri, 22 Jan 2021 14:09:57 +0000 Subject: [Haskell-cafe] stack: duplicate modules in library Message-ID: Solved - thanks to suggestions from Sebastiaan Joosten. A syntax error (missing hyphens) in package.yaml file was creating duplicates in the .cabal file. So nothing to do with cached binary at all. Chris > On 21 Jan 2021, at 13:57, Chris Reade wrote: > > I have come across a problem with haskell stack putting duplicate modules in a library. > > On "stack build" I get > > "Cabal-simple_mPHDZzAJ_3.0.1.0_ghc-8.8.4: Duplicate modules in library:..” > > This may have originally been caused when I changed capitalisation of a filename, but changing back did not resolve the problem. > > My question is how do I get rid of the library so I can rebuild? > I tried "stack purge” and also removing ~/.stack with no luck > (the latter causes a new ghc download on stack build, but with the same message afterwards) > > I know the source modules are fine because they all load in "stack ghci” > Is there some other directory that stack/cabal uses for binary cache that I can safely delete? > > Chris > > > From Juan.Casanova at ed.ac.uk Sun Jan 24 03:15:24 2021 From: Juan.Casanova at ed.ac.uk (CASANOVA Juan) Date: Sun, 24 Jan 2021 03:15:24 +0000 Subject: [Haskell-cafe] Puzzling "Reduction stack overflow" error message Message-ID: Hello Haskell Cafe, I almost feel guilty for posting this since I almost never read messages from this list. But I guess others do and do so because they want to so it's an asymmetry that is fine, and which probably won't be like that forever (I'll get to reading them again at a different stage of my life I'm feeling better). I also have very bad experience with asking "complex" Haskell questions in Stack Overflow, with people either not replying or replying stuff that indicates they did not understand the question. Digression aside, I have encountered this error before and it is a nasty one, but this time I am just wildly puzzled by what it's trying to tell me. This is part of a very large program (and I think the huge stack of types and instances is what is hiding the problem here), but I'll try to condense it into a small bit. The following function I have is the one that throws the error: resolve_to_constraints_metacnf :: SOMetaSignature -> SOMetaCNF -> Computation (Maybe SOMetaUnifSystem) resolve_to_constraints_metacnf sig cnf = result where f1 = (ADDirect <$>) :: SOMetaliteral -> SOMetaUnifLiteral; f2 = (f1 <$>) :: [SOMetaliteral] -> [SOMetaUnifLiteral]; f3 = (f2 <$>) :: [[SOMetaliteral]] -> [[SOMetaUnifLiteral]]; ucnf = f3 cnf :: [[SOMetaUnifLiteral]]; resolved = res_computeresolve SOResGreedyFactorH ucnf :: StateT uv Computation (Maybe SOMetaUnifSystem); runstated = runStateT resolved (UnifVar 0); result = fst <$> runstated The error starts as follows: Reduction stack overflow; size = 201 When simplifying the following type: Eq OFunction The rest is the standard for this type of errors. OFunction does not appear explicitly on my function signature, but if we look at the definitions of SOMetaSignature, SOMetaCNF, SOMetaLiteral, SOMetaUnifLiteral and SOMetaUnifSystem, we see they are type aliases for parameterised types, all of which include OFunction as one of their parameters. Here's an example: type SOMetaUnifLiteral = Literal (AtomDependant CAtomPF CTermF LambdaCNF SOPredicate OPredicate OFunction OVariable SOAMVariable SOMVariable UnifVariable) (Yes, I know how tedious it is to have so many type parameters, tell me about it). And perhaps also relevantly, this is the signature of res_computeresolve (which type checks): res_computeresolve :: (ResLiteral l r mt, Heuristics h [Literal l] () (ResStep l) m) => h -> [[Literal l]] -> mt m (Maybe r) (note, might be relevant, that ResLiteral requires mt to be a MonadTrans and MFunctor, which StateT, the type it gets instantiated to in the calling function, is. m gets instantiated to Computation which is a Monad I implemented myself (and works fine).) Now, the natural thing to think is to track the Constraints to find which one is asking for an Eq OFunction and how that works. It definitely is a constraint that I use all over the place. But, here is the puzzling thing. Eq OFunction is clearly implemented. OFunction is a really simple type. Here is the basic definition: data OFunction = OFun Int Int deriving (Eq, Ord) So, why is it having such a hard time proving Eq OFunction, if it is a really simple type with a derived instance of Eq (which has worked thus far without any issues)? My suspicion is that the message is bugged, and the stack overflow is not on that specific instance, but rather on some type variable on a larger instance that it can never entirely instantiate no matter how many constraints it resolves. This is why I added those inline type signatures to the triple fmap, to try to help GHC know what the types should look like. But I am still getting the error, and I really don't know what else to do now. Sorry for the long message, but since I don't know where the error is coming from, I wanted to give some context, and my entire program is tens of thousands of lines of codes by now... I hope people are able to skim and find the relevant bit that tells them what's likely the stupid mistake I am making. Thanks in advance, Juan. The University of Edinburgh is a charitable body, registered in Scotland, with registration number SC005336. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ietf-dane at dukhovni.org Sun Jan 24 05:06:00 2021 From: ietf-dane at dukhovni.org (Viktor Dukhovni) Date: Sun, 24 Jan 2021 00:06:00 -0500 Subject: [Haskell-cafe] Puzzling "Reduction stack overflow" error message In-Reply-To: References: Message-ID: On Sun, Jan 24, 2021 at 03:15:24AM +0000, CASANOVA Juan wrote: > The following function I have is the one that throws the error: > > resolve_to_constraints_metacnf :: SOMetaSignature -> SOMetaCNF -> Computation (Maybe SOMetaUnifSystem) > resolve_to_constraints_metacnf sig cnf = result > where > f1 = (ADDirect <$>) :: SOMetaliteral -> SOMetaUnifLiteral; > f2 = (f1 <$>) :: [SOMetaliteral] -> [SOMetaUnifLiteral]; > f3 = (f2 <$>) :: [[SOMetaliteral]] -> [[SOMetaUnifLiteral]]; > ucnf = f3 cnf :: [[SOMetaUnifLiteral]]; > resolved = res_computeresolve SOResGreedyFactorH ucnf :: StateT uv Computation (Maybe SOMetaUnifSystem); > runstated = runStateT resolved (UnifVar 0); > result = fst <$> runstated > > The error starts as follows: > > Reduction stack overflow; size = 201 > When simplifying the following type: Eq OFunction This error is reported by: solverDepthErrorTcS :: CtLoc -> TcType -> TcM a solverDepthErrorTcS loc ty = setCtLocM loc $ do { ty <- zonkTcType ty ; env0 <- tcInitTidyEnv ; let tidy_env = tidyFreeTyCoVars env0 (tyCoVarsOfTypeList ty) tidy_ty = tidyType tidy_env ty msg = vcat [ text "Reduction stack overflow; size =" <+> ppr depth , hang (text "When simplifying the following type:") 2 (ppr tidy_ty) , note ] ; failWithTcM (tidy_env, msg) } where depth = ctLocDepth loc note = vcat [ text "Use -freduction-depth=0 to disable this check" , text "(any upper bound you could choose might fail unpredictably with" , text " minor updates to GHC, so disabling the check is recommended if" , text " you're sure that type checking should terminate)" ] Have you tried "-freduction-depth=0"? Does that "terminate"? -- Viktor. From Juan.Casanova at ed.ac.uk Sun Jan 24 17:56:55 2021 From: Juan.Casanova at ed.ac.uk (CASANOVA Juan) Date: Sun, 24 Jan 2021 17:56:55 +0000 Subject: [Haskell-cafe] Puzzling "Reduction stack overflow" error message In-Reply-To: References: , Message-ID: "Have you tried "-freduction-depth=0"? Does that "terminate"?" I had not before you said it. While there is a long tower of constraints, there are no recursive ones that I know of that might drastically increase the depth so I was inclined, by the heuristic that normally just going deeper doesn't solve this kind of problems, not to do it. But I have now, since when you said it I realized it was definitely something to try. I have tried with -freduction-depth=20000, and it still fails (with the same Eq OFunction constraint). With -freduction-depth=1000000 or -freduction-depth=0, it does not terminate within a minute or two. So it does look like there is some infinite depth going on. Thank you for your suggestion anyway. Any more ideas? Mostly I am looking for potential explanations for why it would have an issue with infinite reduction with a constraint that's trivially satisfiable, and then I can try to rationalize that and see how it could apply to my case. Juan Casanova. ________________________________ From: Haskell-Cafe on behalf of Viktor Dukhovni Sent: 24 January 2021 05:06 To: haskell-cafe at haskell.org Subject: Re: [Haskell-cafe] Puzzling "Reduction stack overflow" error message This email was sent to you by someone outside the University. You should only click on links or attachments if you are certain that the email is genuine and the content is safe. On Sun, Jan 24, 2021 at 03:15:24AM +0000, CASANOVA Juan wrote: > The following function I have is the one that throws the error: > > resolve_to_constraints_metacnf :: SOMetaSignature -> SOMetaCNF -> Computation (Maybe SOMetaUnifSystem) > resolve_to_constraints_metacnf sig cnf = result > where > f1 = (ADDirect <$>) :: SOMetaliteral -> SOMetaUnifLiteral; > f2 = (f1 <$>) :: [SOMetaliteral] -> [SOMetaUnifLiteral]; > f3 = (f2 <$>) :: [[SOMetaliteral]] -> [[SOMetaUnifLiteral]]; > ucnf = f3 cnf :: [[SOMetaUnifLiteral]]; > resolved = res_computeresolve SOResGreedyFactorH ucnf :: StateT uv Computation (Maybe SOMetaUnifSystem); > runstated = runStateT resolved (UnifVar 0); > result = fst <$> runstated > > The error starts as follows: > > Reduction stack overflow; size = 201 > When simplifying the following type: Eq OFunction This error is reported by: solverDepthErrorTcS :: CtLoc -> TcType -> TcM a solverDepthErrorTcS loc ty = setCtLocM loc $ do { ty <- zonkTcType ty ; env0 <- tcInitTidyEnv ; let tidy_env = tidyFreeTyCoVars env0 (tyCoVarsOfTypeList ty) tidy_ty = tidyType tidy_env ty msg = vcat [ text "Reduction stack overflow; size =" <+> ppr depth , hang (text "When simplifying the following type:") 2 (ppr tidy_ty) , note ] ; failWithTcM (tidy_env, msg) } where depth = ctLocDepth loc note = vcat [ text "Use -freduction-depth=0 to disable this check" , text "(any upper bound you could choose might fail unpredictably with" , text " minor updates to GHC, so disabling the check is recommended if" , text " you're sure that type checking should terminate)" ] Have you tried "-freduction-depth=0"? Does that "terminate"? -- Viktor. _______________________________________________ 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. The University of Edinburgh is a charitable body, registered in Scotland, with registration number SC005336. -------------- next part -------------- An HTML attachment was scrubbed... URL: From Juan.Casanova at ed.ac.uk Sun Jan 24 19:53:18 2021 From: Juan.Casanova at ed.ac.uk (CASANOVA Juan) Date: Sun, 24 Jan 2021 19:53:18 +0000 Subject: [Haskell-cafe] Puzzling "Reduction stack overflow" error message In-Reply-To: References: , , Message-ID: I fixed it! As I expected, it was a combination of two really silly, really easy to fix, errors. 1. In the line of the error, I was trying to give it a type annotation to make it easier for the type checker, but I forgot to replace the type variable "uv" with the actual type I want it to be using: "UnifVariable". 2. When I fixed this, I got the actual error that was producing this: It was not finding the instance I was expecting it to find. The reason is that I have two types "UnifSystem" and "FullUnifSystem", the latter of which is a wrapper with some extra info for the previous one. The instance is for UnifSystem, but I was feeding it FullUnifSystem to the function, so of course it was not finding the instance (and instead going into some infinite reduction trying to find an instance by replacing the variable "uv" with some magic type that didn't exist). Change FullUnifSystem to UnifSystem (which is what I wanted since the beginning anyway) and now it works. As a reflection, I know these are some of the dangers of using UndecidableInstances, but I found some interesting suggestions for the GHC compiler when trying to debug this, that I wish were already implemented: https://gitlab.haskell.org/ghc/ghc/-/issues/15613 #15613: GHCi command, tracing steps of instance resolution for Constraint or expression · Issues · Glasgow Haskell Compiler / GHC · GitLab Another GHCi command (#15610 (closed)), :elab traces instance resolution for .This is already something people do by hand (ticket:10318# ... gitlab.haskell.org And I found this blog post quite exactly a description of my experience with type classes: https://mgsloan.com/posts/inspecting-haskell-instance-resolution/ [https://mgsloan.com/images/haskell-placeholder-banner.jpg] Inspecting Haskell Instance Resolution An old prototype: explain-instance. I've wanted a solution to this for a long time. 5 years ago, I wrote a prototype, in the form of a Template Haskell library which takes a rather wild approach.It would be much better to implement it directly in GHC, but at the time I was much more familiar with Template Haskell, and the perverse cleverness of the approach has some appeal. mgsloan.com I even downloaded Michael Sloan's ExplainInstances extension to try to help me figure this out, but I couldn't get it to work due to some module version issues. If Michael reads this, I fully support your interest in sorting out this problem. This is not the first time I lose a lot of time trying to debug silly errors like this because I need to reverse engineer what the type checker is trying to do. Thanks to Viktor for the reply again, and to anyone who may have dedicated more than 10 seconds thinking about this. Juan Casanova. ________________________________ From: Haskell-Cafe on behalf of CASANOVA Juan Sent: 24 January 2021 17:56 To: haskell-cafe at haskell.org Subject: Re: [Haskell-cafe] Puzzling "Reduction stack overflow" error message "Have you tried "-freduction-depth=0"? Does that "terminate"?" I had not before you said it. While there is a long tower of constraints, there are no recursive ones that I know of that might drastically increase the depth so I was inclined, by the heuristic that normally just going deeper doesn't solve this kind of problems, not to do it. But I have now, since when you said it I realized it was definitely something to try. I have tried with -freduction-depth=20000, and it still fails (with the same Eq OFunction constraint). With -freduction-depth=1000000 or -freduction-depth=0, it does not terminate within a minute or two. So it does look like there is some infinite depth going on. Thank you for your suggestion anyway. Any more ideas? Mostly I am looking for potential explanations for why it would have an issue with infinite reduction with a constraint that's trivially satisfiable, and then I can try to rationalize that and see how it could apply to my case. Juan Casanova. ________________________________ From: Haskell-Cafe on behalf of Viktor Dukhovni Sent: 24 January 2021 05:06 To: haskell-cafe at haskell.org Subject: Re: [Haskell-cafe] Puzzling "Reduction stack overflow" error message This email was sent to you by someone outside the University. You should only click on links or attachments if you are certain that the email is genuine and the content is safe. On Sun, Jan 24, 2021 at 03:15:24AM +0000, CASANOVA Juan wrote: > The following function I have is the one that throws the error: > > resolve_to_constraints_metacnf :: SOMetaSignature -> SOMetaCNF -> Computation (Maybe SOMetaUnifSystem) > resolve_to_constraints_metacnf sig cnf = result > where > f1 = (ADDirect <$>) :: SOMetaliteral -> SOMetaUnifLiteral; > f2 = (f1 <$>) :: [SOMetaliteral] -> [SOMetaUnifLiteral]; > f3 = (f2 <$>) :: [[SOMetaliteral]] -> [[SOMetaUnifLiteral]]; > ucnf = f3 cnf :: [[SOMetaUnifLiteral]]; > resolved = res_computeresolve SOResGreedyFactorH ucnf :: StateT uv Computation (Maybe SOMetaUnifSystem); > runstated = runStateT resolved (UnifVar 0); > result = fst <$> runstated > > The error starts as follows: > > Reduction stack overflow; size = 201 > When simplifying the following type: Eq OFunction This error is reported by: solverDepthErrorTcS :: CtLoc -> TcType -> TcM a solverDepthErrorTcS loc ty = setCtLocM loc $ do { ty <- zonkTcType ty ; env0 <- tcInitTidyEnv ; let tidy_env = tidyFreeTyCoVars env0 (tyCoVarsOfTypeList ty) tidy_ty = tidyType tidy_env ty msg = vcat [ text "Reduction stack overflow; size =" <+> ppr depth , hang (text "When simplifying the following type:") 2 (ppr tidy_ty) , note ] ; failWithTcM (tidy_env, msg) } where depth = ctLocDepth loc note = vcat [ text "Use -freduction-depth=0 to disable this check" , text "(any upper bound you could choose might fail unpredictably with" , text " minor updates to GHC, so disabling the check is recommended if" , text " you're sure that type checking should terminate)" ] Have you tried "-freduction-depth=0"? Does that "terminate"? -- Viktor. _______________________________________________ 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. The University of Edinburgh is a charitable body, registered in Scotland, with registration number SC005336. -------------- next part -------------- An HTML attachment was scrubbed... URL: From kindaro at gmail.com Mon Jan 25 13:36:17 2021 From: kindaro at gmail.com (Ignat Insarov) Date: Mon, 25 Jan 2021 18:36:17 +0500 Subject: [Haskell-cafe] A quick question about distribution of finite maps. In-Reply-To: References: Message-ID: Hello Olaf and everyone. This is awesome code, much more crisp than what I have been drafting. It highlights that we need to roll out our own dynamic type system to track that the domains of finite maps match where they should. I find it amusing and useful that we can have _«ragged»_ binary maps and currying still works in the absence of empty maps. So there is some space for future work — for instance, maybe non-trivial equality may remove this flaw. Other than that, I think the question is clarified! From olf at aatal-apotheke.de Tue Jan 26 06:16:18 2021 From: olf at aatal-apotheke.de (Olaf Klinke) Date: Tue, 26 Jan 2021 07:16:18 +0100 Subject: [Haskell-cafe] A quick question about distribution of finite maps. In-Reply-To: References: Message-ID: <819b6f0e56a76f22d19f02b5fb69bef4e3542b1d.camel@aatal-apotheke.de> On Mon, 2021-01-25 at 18:36 +0500, Ignat Insarov wrote: > Hello Olaf and everyone. > > This is awesome code, much more crisp than what I have been drafting. > It highlights that we need to roll out our own dynamic type system to > track that the domains of finite maps match where they should. > > I find it amusing and useful that we can have _«ragged»_ binary maps > and currying still works in the absence of empty maps.  Why that? There is Data.Map.empty and it represents any f `restrictedTo` Set.empty > So there is > some space for future work — for instance, maybe non-trivial equality > may remove this flaw. Other than that, I think the question is > clarified! You could explore the design space of subtypes a bit further and let us know how it goes. For example, is FiniteFunction a b = (Set a, a -> b) feasible? Would TypeLevelNats be useful? What about (Set a, a -> b) where Set is a functor of subsets, such as in the infinite-search [*] package? For the special case where type a is a record, there is the records-sop package which has a binary IsSubTypeOf type relation. Olaf [*] For any Eq type, the subsets that admit infinite search are finite. From jm at alliot.org Wed Jan 27 10:48:10 2021 From: jm at alliot.org (Jean-Marc Alliot) Date: Wed, 27 Jan 2021 11:48:10 +0100 Subject: [Haskell-cafe] explicit type for "local" functions Message-ID: <02b05afd-5689-3ed9-851e-2fcd3e9b756c@alliot.org> Just a short and probably simple question. Let's consider the following function: collatz n =   let coll (n,cpt)         | n==1 = (1,cpt)         | even n = coll (div n 2,cpt+1)         | odd n = coll (div (n*3+1) 2,cpt+1) in     snd (coll (n,0)) It is easy to set explicitly the type of "collatz" by writing before the function definition: collatz ::  Integer->Int But can I set explicitly the type of the "local" function "coll" ? Thanks From tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk Wed Jan 27 11:12:26 2021 From: tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk (Tom Ellis) Date: Wed, 27 Jan 2021 11:12:26 +0000 Subject: [Haskell-cafe] explicit type for "local" functions In-Reply-To: <02b05afd-5689-3ed9-851e-2fcd3e9b756c@alliot.org> References: <02b05afd-5689-3ed9-851e-2fcd3e9b756c@alliot.org> Message-ID: <20210127111226.GC16585@cloudinit-builder> On Wed, Jan 27, 2021 at 11:48:10AM +0100, Jean-Marc Alliot wrote: > Let's consider the following function: > collatz n = >   let coll (n,cpt) >         | n==1 = (1,cpt) >         | even n = coll (div n 2,cpt+1) >         | odd n = coll (div (n*3+1) 2,cpt+1) in >     snd (coll (n,0)) [..] > But can I set explicitly the type of the "local" function "coll" ? Do you mean this? collatz :: Integer -> Int collatz n = let coll :: (Integer, Int) -> (Integer, Int) coll (n,cpt) | n==1 = (1,cpt) | even n = coll (div n 2,cpt+1) | odd n = coll (div (n*3+1) 2,cpt+1) in snd (coll (n,0)) From jappie at riskbook.com Wed Jan 27 13:32:41 2021 From: jappie at riskbook.com (Jappie Klooster) Date: Wed, 27 Jan 2021 09:32:41 -0400 Subject: [Haskell-cafe] Take over maintainership binary search Message-ID: Hi, I wish to take over the maintainership of the binary search package. The company I work for (riskbook) currently uses binary search. However the current version doesn't build from hackage because ghc changed how setting files are used, so I made a PR simply deleting that: https://github.com/nushio3/binary-search/pull/3 That has been several months ago and now I'm running against the same issue. There hasn't been a from the author (nushio3), and the email address CC'ed in here are full according to gmail. With regards, Jappie Klooster Riskbook | Software engineer e jappie at riskbook.com p +31644237437 Riskbook is a Limited Company (Company No. 10475714) registered at 1 Adamson Drive, Horsehay, Telford, TF4 3UJ, United Kingdom. All contents of this email should be treated as private and confidential unless otherwise stated. From konn.jinro at gmail.com Thu Jan 28 07:27:19 2021 From: konn.jinro at gmail.com (=?utf-8?B?55+z5LqV5aSn5rW3?=) Date: Thu, 28 Jan 2021 16:27:19 +0900 Subject: [Haskell-cafe] Take over maintainership binary search In-Reply-To: References: Message-ID: Hi Jappie, It is really sad, but I want to note that Muranushi-san, the original author of the package, deceased several years ago [1]. I lament for his prominent talent. I cannot see the procedure in the case maintainer is known to be deceased in Wiki page [2]. I think replacing *maintainer* with *bereaved family of maintainer* makes sense, but I'm not sure. With regards, [1]: http://test.hakubi.kyoto-u.ac.jp/pub/nl14/nl14_Memorial.pdf [2]: http://wiki.haskell.org/Taking_over_a_package -- Hiromi ISHII konn.jinro at gmail.com > 2021/01/27 22:32、Jappie Klooster via Haskell-Cafe のメール: > > Hi, > > I wish to take over the maintainership of the binary search package. > The company I work for (riskbook) currently uses binary search. > However the current version doesn't build from hackage because ghc > changed how setting files are used, so I made a PR simply deleting > that: https://github.com/nushio3/binary-search/pull/3 > That has been several months ago and now I'm running against the same issue. > > There hasn't been a from the author (nushio3), and the email address > CC'ed in here are full according to gmail. > > With regards, > > Jappie Klooster > Riskbook | Software engineer > e jappie at riskbook.com > p +31644237437 > > Riskbook is a Limited Company (Company No. 10475714) registered at 1 > Adamson Drive, Horsehay, Telford, TF4 3UJ, United Kingdom. All > contents of this email should be treated as private and confidential > unless otherwise stated. > _______________________________________________ > 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: -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 488 bytes Desc: Message signed with OpenPGP URL: From david.feuer at gmail.com Thu Jan 28 07:32:14 2021 From: david.feuer at gmail.com (David Feuer) Date: Thu, 28 Jan 2021 02:32:14 -0500 Subject: [Haskell-cafe] Take over maintainership binary search In-Reply-To: References: Message-ID: The case of a sadly deceased maintainer should be handled just like the case for a non-responsive maintainer—the Hackage trustees should be asked to allow Jappie to take over the package. On Thu, Jan 28, 2021, 2:28 AM 石井大海 wrote: > Hi Jappie, > > It is really sad, but I want to note that Muranushi-san, the original > author of the package, > deceased several years ago [1]. I lament for his prominent talent. > > I cannot see the procedure in the case maintainer is known to be deceased > in Wiki page [2]. > I think replacing *maintainer* with *bereaved family of maintainer* makes > sense, but I'm not sure. > > With regards, > > [1]: http://test.hakubi.kyoto-u.ac.jp/pub/nl14/nl14_Memorial.pdf > [2]: http://wiki.haskell.org/Taking_over_a_package > > -- Hiromi ISHII > konn.jinro at gmail.com > > 2021/01/27 22:32、Jappie Klooster via Haskell-Cafe < > haskell-cafe at haskell.org>のメール: > > Hi, > > I wish to take over the maintainership of the binary search package. > The company I work for (riskbook) currently uses binary search. > However the current version doesn't build from hackage because ghc > changed how setting files are used, so I made a PR simply deleting > that: https://github.com/nushio3/binary-search/pull/3 > That has been several months ago and now I'm running against the same > issue. > > There hasn't been a from the author (nushio3), and the email address > CC'ed in here are full according to gmail. > > With regards, > > Jappie Klooster > Riskbook | Software engineer > e jappie at riskbook.com > p +31644237437 > > Riskbook is a Limited Company (Company No. 10475714) registered at 1 > Adamson Drive, Horsehay, Telford, TF4 3UJ, United Kingdom. All > contents of this email should be treated as private and confidential > unless otherwise stated. > _______________________________________________ > 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 jappie at riskbook.com Thu Jan 28 14:40:21 2021 From: jappie at riskbook.com (Jappie Klooster) Date: Thu, 28 Jan 2021 10:40:21 -0400 Subject: [Haskell-cafe] Take over maintainership binary search In-Reply-To: References: Message-ID: Hello Hiromi, First of all my condolences, I did not know the Muranushi had died. For me, the concern is that the package currently doesn't build, yet the company I work for depends on it. I don't particularly mind anyone else taking over maintainership. And if some of his family wants to do that, I'd be happy as well. As long as the issue gets fixed. However, since the company I work for is quite happy to support opensource projects I think it makes a lot of sense for me to take over maintainership. In any case, this particular work of Muranushi would live on. Which hopefully remedies opening this old wound at least a bit. Jappie Klooster Riskbook | Software engineer e jappie at riskbook.com p +31644237437 Riskbook is a Limited Company (Company No. 10475714) registered at 1 Adamson Drive, Horsehay, Telford, TF4 3UJ, United Kingdom. All contents of this email should be treated as private and confidential unless otherwise stated. On Thu, 28 Jan 2021 at 03:32, David Feuer wrote: > The case of a sadly deceased maintainer should be handled just like the > case for a non-responsive maintainer—the Hackage trustees should be asked > to allow Jappie to take over the package. > > On Thu, Jan 28, 2021, 2:28 AM 石井大海 wrote: > >> Hi Jappie, >> >> It is really sad, but I want to note that Muranushi-san, the original >> author of the package, >> deceased several years ago [1]. I lament for his prominent talent. >> >> I cannot see the procedure in the case maintainer is known to be deceased >> in Wiki page [2]. >> I think replacing *maintainer* with *bereaved family of maintainer* >> makes sense, but I'm not sure. >> >> With regards, >> >> [1]: http://test.hakubi.kyoto-u.ac.jp/pub/nl14/nl14_Memorial.pdf >> [2]: http://wiki.haskell.org/Taking_over_a_package >> >> -- Hiromi ISHII >> konn.jinro at gmail.com >> >> 2021/01/27 22:32、Jappie Klooster via Haskell-Cafe < >> haskell-cafe at haskell.org>のメール: >> >> Hi, >> >> I wish to take over the maintainership of the binary search package. >> The company I work for (riskbook) currently uses binary search. >> However the current version doesn't build from hackage because ghc >> changed how setting files are used, so I made a PR simply deleting >> that: https://github.com/nushio3/binary-search/pull/3 >> That has been several months ago and now I'm running against the same >> issue. >> >> There hasn't been a from the author (nushio3), and the email address >> CC'ed in here are full according to gmail. >> >> With regards, >> >> Jappie Klooster >> Riskbook | Software engineer >> e jappie at riskbook.com >> p +31644237437 >> >> Riskbook is a Limited Company (Company No. 10475714) registered at 1 >> Adamson Drive, Horsehay, Telford, TF4 3UJ, United Kingdom. All >> contents of this email should be treated as private and confidential >> unless otherwise stated. >> _______________________________________________ >> 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 matteo at confscience.com Thu Jan 28 20:48:22 2021 From: matteo at confscience.com (matteo at confscience.com) Date: Thu, 28 Jan 2021 21:48:22 +0100 Subject: [Haskell-cafe] International Conference on Recent Theories and Applications in Transportation and Mobility - (RTATM 2021) Prague Message-ID: <003e01d6f5b6$ead18160$c0748420$@confscience.com> Call for papers ************************************************* International Conference on Recent Theories and Applications in Transportation and Mobility - (RTATM 2021) Prague - Czech Republic, October 14-15, 2021 https://confscience.com/rtatm/ Submission deadline: April 1, 2021 All papers accepted in RTATM 2021 will be published in Springer CCIS (Communications in Computer and Information Science). CCIS is abstracted/indexed in Scopus, SCImago, EI-Compendex, Mathematical Reviews, DBLP, Google Scholar, and Thomson Reuters Conference Proceedings Citation (Former ISI Proceedings) *************************************************************************** IMPORTANT DATES: - Paper Submission: April 1, 2021 - Acceptance Notification: July 1, 2021 - Final Manuscript Due: September 1, 2021 *************************************************************************** The RTATM 2021 conference will be held in Conjunction with: International Conference on Applied Data Science and Intelligence (ADSI 2021) International Conference on Informatics Revolution for Smarter Healthcare (IRSH 2021) *************************************************************************** TOPICS: Authors are invited to submit their original papers to address the topics of the conference, including but not limited to: FUNDAMENTALS AND THEORIES - Modelling and Simulation Algorithms - Vehicular Wireless Medium Access Control - V2X communications - Routings and Protocols for Connected Vehicles - Mobility Models and Architectures - Distribution Strategies - Traffic Incident Management Systems - Bio-Inspired Approaches - Optimization and Collaboration - Automatic Control in Vehicular Networks - Energy-aware Connected Mobility - Programming Languages - Sustainable Transportation - Multimodal Transportation Networks and Systems - Systemsb Integration - Driver Behavior Models and Simulation - Human Factors and Travel Behaviour - Green Mobility - Regulations and Bylaws for Intelligent - Transportation and Mobility SMART TRANSPORTATION AND LOGISTICS - Mobility Management - Connected Vehicles - VANETs - Predictive Logistics - Spatio-Temporal Event Tracking - Decision Support Systems - Emergency Management - Logistics and E-Commerce - Supply Chain Design and Execution - Supply Chain Management - Advanced Planning Systems - Fleet Management - Multi-Agent Systems - Machine Learning for Smart Logistics - Intelligent Infrastructures - Real-time Analysis of Comprehensive Supply Chain Data - Smart Synchronization of Logistics Processes - New Approaches for Cost Transparency - Big Data for Smart Logistics - Logistics 4.0 - Mobile Networks - Next-Generation Smart Logistics - Performance Management Approaches - Tests and Deployment - Software Defined Networks - Smart Freight Management - Smart Shipment Management - Smart Warehousing - Smart Inventory management DATA AND SERVICES - Real-Time transportation Data Acquisition - Event Detection and Monitoring - Data Warehouses for connected mobility - Data mining and Data analytics - Data Worthiness in Connected Vehicles - Data Trustworthiness for effective transportation and mobility - Road Traffic Data Analytics - Structured and Unstructured Data for Connected Mobility - Volunteered Geographic Information (VGI) - Data Representation for Connected Mobility - Transportation Data Mining - Transportation and mobility Data Visualization - Cognitive and Context-aware Intelligence - Transportation Decision Support Systems - Mobility as a Service (MaaS) - Intelligent Transportation Services - Smart Mobility Services - Big Data and Vehicle Analytics - Massive Data Management - Collective and connected Intelligence - Next Generation Services - Driver Behaviour Analysis - Geo-Spatial Services - Service-Oriented Architecture (SOA) - Web and Mobile Services SAFETY, SECURITY, AND HAZARD MANAGEMENT - Security Issues in Vehicular Communications - Safety Applications of Connected Vehicles - Weather-related Safety solutions - V2V, V2I and I2V Road Safety Applications - Connected Mobility for Hazard Management - Risk Management - Road Traffic Crashes Analytics - Traffic Jam Prediction - Resource Allocation for Hazard Management - Trust and Privacy Issues in Logistics - Management of Exceptional Events - New approaches to Networking Security for Transportation Applications - Failure modes, human factors, software safety - Automated Failure Analysis - Performance and Human Error Analysis - Design and Reliability of Control Systems - Dispersion Modelling Software - Quantification of Risk *************************************************************************** OUTSTANDING PAPERS: Based on the peer review scores as well as the presentations at the conference, the authors of outstanding papers will be invited to extend their works for a potential publication in journals special issues with high impact factors. *************************************************************************** PAPER SUBMISSION: Papers must be submitted electronically as PDF files via easychair (https://easychair.org/conferences/?conf=rtatm2021). All papers will be peer reviewed. Length of Full papers: 12-15 pages long (written in the LNCS/CCIS one-column page format, 400 words per page) Length of Short papers: less than 12 pages For more information, please refer to the conference website: https://confscience.com/rtatm/ *************************************************************************** CONTACT For more information, please send an email to info-rtatm at confscience.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From kolar at fit.vut.cz Fri Jan 29 09:57:07 2021 From: kolar at fit.vut.cz (=?utf-8?B?RHXFoWFuIEtvbMOhxZk=?=) Date: Fri, 29 Jan 2021 10:57:07 +0100 Subject: [Haskell-cafe] Compilation of large data Message-ID: <3767409.SCssA4BfgB@nbkolard> Dear Café, How can I compile large data in the source code? The data structure contains a few numerical and String constants and a long list of structures (containing two short lists of Strings). If I use ghci, it's fine, no problem (until some size). When I want to compile then I run out of memory (32GB, plus 32GB swap) on arch linux. Yes, machine with 256GB solved temporarily the problem, but only temporarily. The data is generated (about 10.000 elements for the list and more). Should it be read from the file during the runtime? Should the structure be somehow decoupled (to small lists, each of them in a separate file)? Or there is no way, how to make it work... :-( If I use different input, a bit smaller, which I can compile, the resulting binary is rather small, less than 7MB. Regards Dušan -------------- next part -------------- An HTML attachment was scrubbed... URL: From sylvain at haskus.fr Fri Jan 29 11:50:51 2021 From: sylvain at haskus.fr (Sylvain Henry) Date: Fri, 29 Jan 2021 12:50:51 +0100 Subject: [Haskell-cafe] Compilation of large data In-Reply-To: <3767409.SCssA4BfgB@nbkolard> References: <3767409.SCssA4BfgB@nbkolard> Message-ID: <4c7cff43-46f1-2554-94d7-37a658ab8e4f@haskus.fr> Hi Dušan, Could you open a GHC ticket with a reproducing example? It looks similar to https://gitlab.haskell.org/ghc/ghc/-/issues/16577 so you may have more chance with `-O0`. Thanks, Sylvain On 29/01/2021 10:57, Dušan Kolář wrote: > > Dear Café, > > > How can I compile large data in the source code? The data structure > contains a few numerical and String constants and a long list of > structures (containing two short lists of Strings). > > > If I use ghci, it's fine, no problem (until some size). When I want to > compile then I run out of memory (32GB, plus 32GB swap) on arch linux. > Yes, machine with 256GB solved temporarily the problem, but only > temporarily. > > > The data is generated (about 10.000 elements for the list and more). > Should it be read from the file during the runtime? Should the > structure be somehow decoupled (to small lists, each of them in a > separate file)? Or there is no way, how to make it work... :-( > > > If I use different input, a bit smaller, which I can compile, the > resulting binary is rather small, less than 7MB. > > > Regards > > > Dušan > > > > _______________________________________________ > 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 lemming at henning-thielemann.de Fri Jan 29 12:22:24 2021 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Fri, 29 Jan 2021 13:22:24 +0100 (CET) Subject: [Haskell-cafe] Compilation of large data In-Reply-To: <4c7cff43-46f1-2554-94d7-37a658ab8e4f@haskus.fr> References: <3767409.SCssA4BfgB@nbkolard> <4c7cff43-46f1-2554-94d7-37a658ab8e4f@haskus.fr> Message-ID: <92b1654b-34e7-7959-d3f2-304fde4ca71@henning-thielemann.de> On Fri, 29 Jan 2021, Sylvain Henry wrote: > Could you open a GHC ticket with a reproducing example? > > It looks similar to https://gitlab.haskell.org/ghc/ghc/-/issues/16577 so you may have more chance with `-O0`. If disabling optimization helps, then it might be useful to disable it only for this module by adding a pragma to the top of the module: {-# OPTIONS_GHC -O0 #-} From kolar at fit.vut.cz Fri Jan 29 13:25:52 2021 From: kolar at fit.vut.cz (=?utf-8?B?RHXFoWFuIEtvbMOhxZk=?=) Date: Fri, 29 Jan 2021 14:25:52 +0100 Subject: [Haskell-cafe] Compilation of large data In-Reply-To: <92b1654b-34e7-7959-d3f2-304fde4ca71@henning-thielemann.de> References: <3767409.SCssA4BfgB@nbkolard> <4c7cff43-46f1-2554-94d7-37a658ab8e4f@haskus.fr> <92b1654b-34e7-7959-d3f2-304fde4ca71@henning-thielemann.de> Message-ID: <1682098.CQeEDlsRJd@pckolar> So -O0 didn't help. Nevertheless, ghc suggests to read it from file :-) "... ghc: sorry! (unimplemented feature or known bug) (GHC version 8.6.3 for x86_64-unknown-linux): Trying to allocate more than 129024 bytes. This is currently not possible due to a limitation of GHC's code generator. See http://hackage.haskell.org/trac/ghc/ticket/4505 for details. Suggestion: read data from a file instead of having large static data structures in code. ..." It seems that splitting the list into several modules (several thousands of elements per list are OK) works. Moreover, as it is generated, several modules can be generated too. And even more, efficiency is not affected (the same execution time and -O2 used for all modules). Regards (and over :-)) Dušan On pátek 29. ledna 2021 13:22:24 CET Henning Thielemann wrote: > On Fri, 29 Jan 2021, Sylvain Henry wrote: > > Could you open a GHC ticket with a reproducing example? > > > > It looks similar to https://gitlab.haskell.org/ghc/ghc/-/issues/16577 so > > you may have more chance with `-O0`. > If disabling optimization helps, then it might be useful to disable it > only for this module by adding a pragma to the top of the module: > > {-# OPTIONS_GHC -O0 #-} > _______________________________________________ > 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. -- Dusan Kolar tel: +420 54 114 1238 UIFS FIT VUT Brno fax: +420 54 114 1270 Bozetechova 2 e-mail: kolar at fit.vut.cz Brno 612 66 Czech Republic -- -------------- next part -------------- An HTML attachment was scrubbed... URL: From carter.schonwald at gmail.com Fri Jan 29 14:22:52 2021 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Fri, 29 Jan 2021 09:22:52 -0500 Subject: [Haskell-cafe] Compilation of large data In-Reply-To: <1682098.CQeEDlsRJd@pckolar> References: <3767409.SCssA4BfgB@nbkolard> <4c7cff43-46f1-2554-94d7-37a658ab8e4f@haskus.fr> <92b1654b-34e7-7959-d3f2-304fde4ca71@henning-thielemann.de> <1682098.CQeEDlsRJd@pckolar> Message-ID: For truly monster static data, I’ve had success with putting into a c file. But for interesting data structures this can be not ideal. On Fri, Jan 29, 2021 at 8:26 AM Dušan Kolář wrote: > So -O0 didn't help. > > Nevertheless, ghc suggests to read it from file :-) > > "... > > ghc: sorry! (unimplemented feature or known bug) > > (GHC version 8.6.3 for x86_64-unknown-linux): > > Trying to allocate more than 129024 bytes. > > This is currently not possible due to a limitation of GHC's code generator. > > See http://hackage.haskell.org/trac/ghc/ticket/4505 for details. > > Suggestion: read data from a file instead of having large static data > > structures in code. > > ..." > > It seems that splitting the list into several modules (several thousands > of elements per list are OK) works. Moreover, as it is generated, several > modules can be generated too. And even more, efficiency is not affected > (the same execution time and -O2 used for all modules). > > Regards (and over :-)) > > Dušan > > On pátek 29. ledna 2021 13:22:24 CET Henning Thielemann wrote: > > > On Fri, 29 Jan 2021, Sylvain Henry wrote: > > > > Could you open a GHC ticket with a reproducing example? > > > > > > > > It looks similar to https://gitlab.haskell.org/ghc/ghc/-/issues/16577 > so > > > > you may have more chance with `-O0`. > > > If disabling optimization helps, then it might be useful to disable it > > > only for this module by adding a pragma to the top of the module: > > > > > > {-# OPTIONS_GHC -O0 #-} > > > _______________________________________________ > > > 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. > > -- > > Dusan Kolar tel: +420 54 114 1238 > > UIFS FIT VUT Brno fax: +420 54 114 1270 > > Bozetechova 2 > > e-mail: kolar at fit.vut.cz > > Brno 612 66 > > Czech Republic > > -- > > _______________________________________________ > 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 han.joosten.han at gmail.com Fri Jan 29 20:38:45 2021 From: han.joosten.han at gmail.com (Han Joosten) Date: Fri, 29 Jan 2021 21:38:45 +0100 Subject: [Haskell-cafe] Project builds with stack, not with cabal. How to diagnose? Message-ID: Dear Café, I have been building my project for quite some time now using Stack. That works fine. However, I also want to make sure cabal users can build it from source. Recently I have been trying to set this up using github actions. I use a matrix to build both with stack and with cabal. I use the same version of ghc. A recent build can be seen here: https://github.com/AmpersandTarski/Ampersand/runs/1756887612 I guess that the error is due to the fact that the used packages to build are somehow different between the stack build and the cabal build. Is there some way to find out what those differences are? Any help would be appreciated! Thanks Han Joosten -------------- next part -------------- An HTML attachment was scrubbed... URL: From simon.jakobi at googlemail.com Fri Jan 29 21:15:26 2021 From: simon.jakobi at googlemail.com (Simon Jakobi) Date: Fri, 29 Jan 2021 22:15:26 +0100 Subject: [Haskell-cafe] Project builds with stack, not with cabal. How to diagnose? In-Reply-To: References: Message-ID: (I forgot to CC the list) Hi Han, with stack, you can use `stack ls dependencies` to get a list of your dependencies with versions. With cabal, you can use `cabal freeze`. The error message you linked indicates that changes in microlens or lens might be the problem. Both have exported (^?) for a long time though. It turns out that you're re-exporting the entirety of RIO from Ampersand.Basics (via Ampersand.Basics.Prelude). And RIO has only recently begun to export parts of microlens: http://hackage.haskell.org/package/rio-0.1.20.0/changelog. Cheers, Simon Am Fr., 29. Jan. 2021 um 21:47 Uhr schrieb Han Joosten < han.joosten.han at gmail.com>: > > > Dear Café, > > I have been building my project for quite some time now using Stack. That > works fine. However, I also want to make sure cabal users can build it from > source. > > Recently I have been trying to set this up using github actions. I use a > matrix to build both with stack and with cabal. I use the same version of > ghc. > > A recent build can be seen here: > https://github.com/AmpersandTarski/Ampersand/runs/1756887612 > > I guess that the error is due to the fact that the used packages to build > are somehow different between the stack build and the cabal build. > Is there some way to find out what those differences are? > > Any help would be appreciated! > > Thanks > > Han Joosten > _______________________________________________ > 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 Fri Jan 29 21:23:27 2021 From: alan.zimm at gmail.com (Alan & Kim Zimmerman) Date: Fri, 29 Jan 2021 21:23:27 +0000 Subject: [Haskell-cafe] PSA: IRC #haskell-ide-engine has moved to #haskell-language-server Message-ID: Given haskell-ide-engine is retired, we have moved the IRC channel to something more appropriate. Alan -------------- next part -------------- An HTML attachment was scrubbed... URL: From han.joosten.han at gmail.com Sat Jan 30 10:56:47 2021 From: han.joosten.han at gmail.com (Han Joosten) Date: Sat, 30 Jan 2021 11:56:47 +0100 Subject: [Haskell-cafe] Project builds with stack, not with cabal. How to diagnose? In-Reply-To: References: Message-ID: Hi Simon, Thank you very much for this great help. I Have created an issue for my project, so I can follow up on my findings and fix this. I have run both ways to get dependency lists, and tbh I am pretty astonished by the amount and sort of differences. More on this in mentioned issue: https://github.com/AmpersandTarski/Ampersand/issues/1142 Again, Thanks a lot! Cheers, Han Op vr 29 jan. 2021 om 22:15 schreef Simon Jakobi < simon.jakobi at googlemail.com>: > (I forgot to CC the list) > > Hi Han, > > with stack, you can use `stack ls dependencies` to get a list of your > dependencies with versions. With cabal, you can use `cabal freeze`. > > The error message you linked indicates that changes in microlens or lens > might be the problem. Both have exported (^?) for a long time though. It > turns out that you're re-exporting the entirety of RIO from > Ampersand.Basics (via Ampersand.Basics.Prelude). And RIO has only recently > begun to export parts of microlens: > http://hackage.haskell.org/package/rio-0.1.20.0/changelog. > > Cheers, > Simon > > Am Fr., 29. Jan. 2021 um 21:47 Uhr schrieb Han Joosten < > han.joosten.han at gmail.com>: > >> >> >> Dear Café, >> >> I have been building my project for quite some time now using Stack. That >> works fine. However, I also want to make sure cabal users can build it from >> source. >> >> Recently I have been trying to set this up using github actions. I use a >> matrix to build both with stack and with cabal. I use the same version of >> ghc. >> >> A recent build can be seen here: >> https://github.com/AmpersandTarski/Ampersand/runs/1756887612 >> >> I guess that the error is due to the fact that the used packages to build >> are somehow different between the stack build and the cabal build. >> Is there some way to find out what those differences are? >> >> Any help would be appreciated! >> >> Thanks >> >> Han Joosten >> _______________________________________________ >> 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: