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: