From zubin at well-typed.com Fri Dec 1 13:34:34 2023 From: zubin at well-typed.com (Zubin Duggal) Date: Fri, 1 Dec 2023 19:04:34 +0530 Subject: [Haskell-cafe] [Haskell] [ANNOUNCE] Haskell Language Server 2.5.0.0 released Message-ID: Binaries for this release are available at https://downloads.haskell.org/~hls/haskell-language-server-2.5.0.0/. These binaries can be installed using [GHCup](https://www.haskell.org/ghcup/), using the vanilla metadata channel: ghcup --url-source=https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-vanilla-0.0.8.yaml install hls 2.5.0.0 All of these tarballs have associated GPG signatures. The signature should be from `Zubin Duggal ` (key ID [588764FBE22D19C4](https://keys.openpgp.org/search?q=588764FBE22D19C4)). The prebuilt binaries in this release support the following GHC versions: - 9.2.8 - 9.4.8 - 9.6.3 - 9.8.1 # Changelog - Bindists for GHC 9.4.8 - Drop support for GHC 9.0 - Re-add stan plugin - Load default operator fixities in Fourmolu plugin Happy editing! - Zubin -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 488 bytes Desc: not available URL: From lysxia at gmail.com Fri Dec 1 15:03:17 2023 From: lysxia at gmail.com (Li-yao Xia) Date: Fri, 1 Dec 2023 15:03:17 +0000 Subject: [Haskell-cafe] Does the constraints library give (a :- b) -> Dict (a |- b)? In-Reply-To: References: Message-ID: Hi Tom, There is an issue with bottoms/nontermination (which I don't see mentioned in those threads). If you have coimply :: (Dict a -> Dict b) -> Dict (a |- b), then you can apply it to (const undefined) and obtain this paradox: 1. coimply f :: Dict (a |- b) should never be bottom (const undefined is in fact a legitimate value for f: you could have b a one-method type class with one instance that's undefined). 2. If c is unsatisfiable, (d :: Dict c) must be bottom. Violating property 2 lets you "satisfy the unsatisfiable". For example, you can then apply a function of type (True ~ False) => t, which GHC expects to never be called and will in fact optimize away based on that assumption. See code below for a concrete example (which includes a plausible definition of coimply). If you can restrict the argument of coimply so as to avoid that problem, then it is plausible that you can preserve the uniqueness of instances, which seems to be the one property of type classes that we care about in Haskell (which is already broken by orphan instances and some obscure corners of overlapping instances if I recall correctly, so there is already precedent for not enforcing this property automatically). Cheers, Li-yao --- {-# LANGUAGE DataKinds, GADTs, QuantifiedConstraints, RankNTypes, UndecidableInstances, MagicHash, ScopedTypeVariables #-} module Main where import Data.Kind import GHC.Exts (Any) import Unsafe.Coerce -- Unsafe internals -- "Unboxed dictionaries" (as opposed to Dict) newtype Dict# c = Dict# Any idDict# :: forall c. c :- Dict# c idDict# = unsafeCoerce (\x -> x :: Dict# c) applyDict# :: forall c t. c :- t -> Dict# c -> t applyDict# = unsafeCoerce class (c => d) => Implies c d instance (c => d) => Implies c d apDict# :: forall c d. (Dict# c -> Dict# d) -> Dict# (Implies c d) apDict# = unsafeCoerce toDict :: Dict# c -> Dict c toDict = applyDict# ((:-) Dict) toDict# :: forall c. Dict c -> Dict# c toDict# Dict = case idDict# @c of (:-) f -> f -- Constraints library data Dict (c :: Constraint) where Dict :: c => Dict c newtype (:-) c t = (:-) (c => t) applyDict :: c :- t -> Dict c -> t applyDict ((:-) f) Dict = f -- coimply apDict :: (Dict c -> Dict d) -> Dict (Implies c d) apDict f = toDict (apDict# (toDict# . f . toDict)) -- Example (broken) usage class Unsat instance True ~ False => Unsat -- You can also just replace Unsat with True ~ False, -- which causes GHC to "optimize" away the code of uncallable to a noop uncallable :: Unsat :- a uncallable = (:-) (error "THE IMPOSSIBLE HAPPENED") fake :: Dict Unsat fake = case apDict (\_ -> error "fake dictionary") :: Dict (Implies () Unsat) of Dict -> Dict main :: IO () main = do putStrLn "Hi" applyDict uncallable fake putStrLn "Bye" On Thu, Nov 30, 2023 at 2:33 PM Tom Ellis wrote: > > On Thu, Nov 30, 2023 at 01:37:47PM +0000, Tom Ellis wrote: > > The constraints library [1] has > > > > implied :: forall a b. (a => b) => a :- b > > > > from which I can obtain > > > > implied' :: Dict (a |- b) -> a :- b > > implied' Dict = implied > > > > but can I get the converse of this, that is > > > > coimplied :: (a :- b) -> Dict (a |- b) > > coimplied = error "Can it be done?" > > > > I don't see how. The library itself only mentions "|-" in its > > definition. Would this combinator violate some guarantee that's > > essential for the safe use of type classes? > > It seems this question has been asked at least a couple of times of > the GHC bug tracker, firstly in > > https://gitlab.haskell.org/ghc/ghc/-/issues/14822 > > where it was deemed unsound (I don't understand why) and again in > > https://gitlab.haskell.org/ghc/ghc/-/issues/14937 > > where it remains open without having explicitly been deemed unsound. > > Tom > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From tom-lists-haskell-cafe-2023 at jaguarpaw.co.uk Fri Dec 1 15:46:43 2023 From: tom-lists-haskell-cafe-2023 at jaguarpaw.co.uk (Tom Ellis) Date: Fri, 1 Dec 2023 15:46:43 +0000 Subject: [Haskell-cafe] Does the constraints library give (a :- b) -> Dict (a |- b)? In-Reply-To: References: Message-ID: On Fri, Dec 01, 2023 at 03:03:17PM +0000, Li-yao Xia wrote: > There is an issue with bottoms/nontermination (which I don't see > mentioned in those threads). Yes, but can we resolve it by simply removing the possibility for bottom, e.g. by making Dict unlifted? The below code seems to be fine for example (it prints "fake dictionary"), and that only relies on making sure that the Dict# is sufficiently evaluated. Tom unImply# :: forall c d. Dict# (Implies c d) -> Dict# c -> Dict# d unImply# (Dict# f) (Dict# c) = Dict# (unsafeCoerce f c) toDict :: Dict# c -> Dict c toDict !d = applyDict# ((:-) Dict) d fake# :: Dict# Unsat fake# = unImply# (apDict# (\_ -> error "fake dictionary") :: Dict# (Implies () Unsat)) (toDict# Dict) main :: IO () main = do putStrLn "Hi" applyDict uncallable (toDict fake#) putStrLn "Bye" From tom-lists-haskell-cafe-2023 at jaguarpaw.co.uk Fri Dec 1 16:12:43 2023 From: tom-lists-haskell-cafe-2023 at jaguarpaw.co.uk (Tom Ellis) Date: Fri, 1 Dec 2023 16:12:43 +0000 Subject: [Haskell-cafe] Does the constraints library give (a :- b) -> Dict (a |- b)? In-Reply-To: References: Message-ID: On Fri, Dec 01, 2023 at 03:46:43PM +0000, Tom Ellis wrote: > On Fri, Dec 01, 2023 at 03:03:17PM +0000, Li-yao Xia wrote: > > There is an issue with bottoms/nontermination (which I don't see > > mentioned in those threads). > > Yes, but can we resolve it by simply removing the possibility for > bottom, e.g. by making Dict unlifted? The below code seems to be fine > for example (it prints "fake dictionary"), and that only relies on > making sure that the Dict# is sufficiently evaluated. Making Dict# unlifted also seems to resolve the issue. What do you think? Is this sufficient in general to resolve the unsoundness you spotted? Tom type Dict# :: Constraint -> TYPE UnliftedRep newtype Dict# c = Dict# Any apDict# :: forall c d. (Dict# c -> Dict# d) -> Dict# (Implies c d) apDict# = unsafeCoerce id unImply# :: forall c d. Dict# (Implies c d) -> Dict# c -> Dict# d unImply# (Dict# f) (Dict# c) = Dict# (unsafeCoerce id f c) fake# :: () -> Dict# Unsat fake# () = unImply# (apDict# (\_ -> error "fake dictionary") :: Dict# (Implies () Unsat)) (toDict# Dict) main :: IO () main = do putStrLn "Hi" let !_ = applyDict uncallable (toDict (fake# ())) putStrLn "Bye" From lysxia at gmail.com Fri Dec 1 18:04:53 2023 From: lysxia at gmail.com (Li-yao Xia) Date: Fri, 1 Dec 2023 18:04:53 +0000 Subject: [Haskell-cafe] Does the constraints library give (a :- b) -> Dict (a |- b)? In-Reply-To: References: Message-ID: Not quite. Your version uses an ad hoc unImply# to force the application, but you can already use the more general (applyDict# :: ((c => d) => t) -> Dict# (Implies c d) -> t) to lift the implication itself as a constraint (c => d), which GHC then wrongly assumes to be "well-defined" by construction. See example below. I think your idea of making things stricter is going in the right direction, but the laziness that you need to get rid of seems deeply ingrained in GHC. --- type Dict# :: Constraint -> TYPE UnliftedRep newtype Dict# c = Dict# Any uncallable :: (True ~ False) :- a uncallable = (:-) (error "THE IMPOSSIBLE HAPPENED") main :: IO () main = do putStrLn "Hi" applyDict# ((:-) (case uncallable of (:-) f -> f)) (apDict# (\_ -> error "fake dictionary") :: Dict# (Implies (Implies () ()) (True ~ False))) putStrLn "Bye" On Fri, Dec 1, 2023 at 4:13 PM Tom Ellis wrote: > > On Fri, Dec 01, 2023 at 03:46:43PM +0000, Tom Ellis wrote: > > On Fri, Dec 01, 2023 at 03:03:17PM +0000, Li-yao Xia wrote: > > > There is an issue with bottoms/nontermination (which I don't see > > > mentioned in those threads). > > > > Yes, but can we resolve it by simply removing the possibility for > > bottom, e.g. by making Dict unlifted? The below code seems to be fine > > for example (it prints "fake dictionary"), and that only relies on > > making sure that the Dict# is sufficiently evaluated. > > Making Dict# unlifted also seems to resolve the issue. What do you > think? Is this sufficient in general to resolve the unsoundness you > spotted? > > > Tom > > > type Dict# :: Constraint -> TYPE UnliftedRep > newtype Dict# c = Dict# Any > > apDict# :: forall c d. (Dict# c -> Dict# d) -> Dict# (Implies c d) > apDict# = unsafeCoerce id > > unImply# :: forall c d. Dict# (Implies c d) -> Dict# c -> Dict# d > unImply# (Dict# f) (Dict# c) = Dict# (unsafeCoerce id f c) > > fake# :: () -> Dict# Unsat > fake# () = > unImply# > (apDict# (\_ -> error "fake dictionary") :: Dict# (Implies () Unsat)) > (toDict# Dict) > > main :: IO () > main = do > putStrLn "Hi" > let !_ = applyDict uncallable (toDict (fake# ())) > putStrLn "Bye" > _______________________________________________ > 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 tom-lists-haskell-cafe-2023 at jaguarpaw.co.uk Fri Dec 1 19:33:44 2023 From: tom-lists-haskell-cafe-2023 at jaguarpaw.co.uk (Tom Ellis) Date: Fri, 1 Dec 2023 19:33:44 +0000 Subject: [Haskell-cafe] Does the constraints library give (a :- b) -> Dict (a |- b)? In-Reply-To: References: Message-ID: Ah yes, thanks, I see! Actually, this version seems to be sufficient to show the problem: main :: IO () main = do putStrLn "Hi" applyDict# uncallable (apDict# (\_ -> error "fake dictionary") :: Dict# (Implies () (True ~ False))) putStrLn "Bye" We can make the constraint `Implies () (True ~ False)` which is neither bottom nor a correct constraint and then it's GHC itself which solves the `()` constraint, applying it to unveil bottom; in userland we don't get a chance to test it for bottomness. I think there's yet some hope we could build up the constraints using a more restrictive set of combinators, rather than (->), which would guarantee that all constraints produced that way are either bottom or total. Seems to be difficult but thorny territory though. Thanks again for your help discovering the flaw with this idea. Tom On Fri, Dec 01, 2023 at 06:04:53PM +0000, Li-yao Xia wrote: > Not quite. Your version uses an ad hoc unImply# to force the > application, but you can already use the more general (applyDict# :: > ((c => d) => t) -> Dict# (Implies c d) -> t) to lift the implication > itself as a constraint (c => d), which GHC then wrongly assumes to be > "well-defined" by construction. See example below. I think your idea > of making things stricter is going in the right direction, but the > laziness that you need to get rid of seems deeply ingrained in GHC. > > --- > > type Dict# :: Constraint -> TYPE UnliftedRep > newtype Dict# c = Dict# Any > > uncallable :: (True ~ False) :- a > uncallable = (:-) (error "THE IMPOSSIBLE HAPPENED") > > main :: IO () > main = do > putStrLn "Hi" > applyDict# > ((:-) (case uncallable of (:-) f -> f)) > (apDict# (\_ -> error "fake dictionary") :: Dict# (Implies > (Implies () ()) (True ~ False))) > putStrLn "Bye" > > > On Fri, Dec 1, 2023 at 4:13 PM Tom Ellis > wrote: > > > > On Fri, Dec 01, 2023 at 03:46:43PM +0000, Tom Ellis wrote: > > > On Fri, Dec 01, 2023 at 03:03:17PM +0000, Li-yao Xia wrote: > > > > There is an issue with bottoms/nontermination (which I don't see > > > > mentioned in those threads). > > > > > > Yes, but can we resolve it by simply removing the possibility for > > > bottom, e.g. by making Dict unlifted? The below code seems to be fine > > > for example (it prints "fake dictionary"), and that only relies on > > > making sure that the Dict# is sufficiently evaluated. > > > > Making Dict# unlifted also seems to resolve the issue. What do you > > think? Is this sufficient in general to resolve the unsoundness you > > spotted? > > > > > > Tom > > > > > > type Dict# :: Constraint -> TYPE UnliftedRep > > newtype Dict# c = Dict# Any > > > > apDict# :: forall c d. (Dict# c -> Dict# d) -> Dict# (Implies c d) > > apDict# = unsafeCoerce id > > > > unImply# :: forall c d. Dict# (Implies c d) -> Dict# c -> Dict# d > > unImply# (Dict# f) (Dict# c) = Dict# (unsafeCoerce id f c) > > > > fake# :: () -> Dict# Unsat > > fake# () = > > unImply# > > (apDict# (\_ -> error "fake dictionary") :: Dict# (Implies () Unsat)) > > (toDict# Dict) > > > > main :: IO () > > main = do > > putStrLn "Hi" > > let !_ = applyDict uncallable (toDict (fake# ())) > > putStrLn "Bye" From julia.longtin at gmail.com Fri Dec 1 21:18:59 2023 From: julia.longtin at gmail.com (Julia Longtin) Date: Fri, 1 Dec 2023 22:18:59 +0100 Subject: [Haskell-cafe] Request to take over floating-bits package Message-ID: This is an attempt to follow the process at wiki.haskell.org/Taking_over_a_package I have set up a git repository at github.com/julialongtin/floating-bits/ , and fixed compatibility issues with ghc-9.4. I would like to be made maintainer of this package in hackage. Julia Longtin -------------- next part -------------- An HTML attachment was scrubbed... URL: From simon at joyful.com Sat Dec 2 05:57:38 2023 From: simon at joyful.com (Simon Michael) Date: Fri, 1 Dec 2023 19:57:38 -1000 Subject: [Haskell-cafe] ANN: hledger 1.32 Message-ID: <30100C44-FD30-4842-B502-F4B8D08D7646@joyful.com> G'day all, I'm very pleased to announce hledger 1.32, including work from contributors Jonathan Dowland, S. Zeid, Charlie Ambrose, Jacob Weisz, Peter Sagerson, Philipp Klocke, Stephen Morgan, and bobobo1618. Highlights: More precision control, beancount output, TSV output, --summary-only, strict/idempotent import, CSV rule enhancements, timedot letters, fixes - there's a lot in this one, set aside some time to read the notes. - https://github.com/simonmichael/hledger/releases/1.32 - https://hledger.org/release-notes.html#2023-12-01-hledger-132 - https://hledger.org/install hledger is free, fast, reliable, multicurrency, double-entry, plain text accounting software for unix, mac, windows, and the web; built around human-readable, version-controllable plain text files; inspired by and largely compatible with Ledger CLI; convertible to and from Beancount; written in Haskell for reliability and longevity. For help getting started or more info, see https://hledger.org and join our Matrix/IRC chat or mail list: https://hledger.org/support . Newcomers, experts, contributors, sponsors, feedback are welcome! For more about plain text accounting, see https://plaintextaccounting.org . May you be free from danger; may you have happy, peaceful, prosperous holidays. -Simon From jkarni at gmail.com Sun Dec 3 16:06:14 2023 From: jkarni at gmail.com (Julian Arni) Date: Sun, 3 Dec 2023 17:06:14 +0100 Subject: [Haskell-cafe] garn: a Nix/Cabal/Stack alternative Message-ID: Dear list, garn is a new take on Nix - configured in Typescript rather than the Nix language, and with a nicer and simpler CLI (thanks optparse-applicative!). The repository is https://github.com/garnix-io/garn, and the website is https://garn.io/. I'm mentioning it here because we just added better Haskell support, which makes it now a plausible alternative to managing your Haskell projects with Nix, Stack or Cabal. An example Haskell project: import * as garn from "https://garn.io/ts/v0.0.18/mod.ts"; import * as pkgs from "https://garn.io/ts/v0.0.18/nixpkgs.ts"; export const project = garn.haskell.mkHaskellProject({ description: "My project", src: ".", executables: ["server", "openapi-generation"] overrideDependencies: { "servant": "0.19.1" }, ghcVersion: "ghc94" }).addExecutable("format")`${pkgs.ormolu}/bin/ormolu --mode inplace $(find . -name '*.hs')` Which allows for `garn build project` to build the project, and `garn enter project` to be in a devshell with cabal, ghc94 and all the dependencies installed, and `garn run project.format` for formatting all files with ormolu. (`garn init` is capable of generating most of that file for you.) # Comparisons First, compared to all of the options below, garn is much less mature - there'll be rougher edges or features not yet supported. It's also still changing very quickly, and backwards compatibility is not, for now, a priority. - Cabal: Like Cabal, garn still uses a cabal file, and in fact expects you to develop with cabal. garn brings in the dependencies itself and makes them known to ghc/cabal, and they're snapshot-based rather than resolver-based. In addition, garn makes it easy to include system (non-Haskell) dependencies, it sandboxes builds and tests for better reproduciblity (making CI in particular quite easy); it allows for shared caches; it supports scripts for project janitoring and management; and it supports devshells. - Stack: Like Stack, garn uses a snapshot-based approach to dependencies. In fact, it's based on the stackage releases. It also supports overriding versions from Hackage, but not yet from git. Unlike Stack, it allows specifying system dependencies (non-Haskell dependencies); it sandboxes builds and tests for better reproduciblity (making CI in particular quite easy); it allows for shared caches; it supports scripts for project janitoring and management; and it supports devshells. - Nix: the focus of garn has been a simplified and more productive user experience when compared to Nix. A typed language means you can get autocompletion, documentation, and type errors in your editor, for example. And, even if Typescript is by no means perfect, it's much easier to program in than Nix, so it becomes more fun to abstract away functionality (e.g.: an addGhcidToProject function). garn "transpiles" to Nix, and Nix can be embedded in garn, so the choice is not binary. # Feedback If you try it out, please let us know what you think, or if you run into any roadblocks. You can email me at this address, or open issues on GitHub, or join the Discord channel at https://discord.com/invite/XtDrPsqpVx. It also happens to be partly written in Haskell; hopefully that makes it more easy and fun to get involved! Cheers, Julian -------------- next part -------------- An HTML attachment was scrubbed... URL: From ihabmohsen at proton.me Tue Dec 5 11:54:36 2023 From: ihabmohsen at proton.me (Ihab Mohsen) Date: Tue, 05 Dec 2023 11:54:36 +0000 Subject: [Haskell-cafe] Elevate Safety with ATISystems.com: Your Destination for Cutting-Edge Giant Voice and Outdoor Warning Systems Message-ID: Ensuring safety and security in outdoor spaces stands as a paramount concern, and [ATISystems.com](http://atisystems.com/) leads the way with innovative solutions crafted to safeguard communities and businesses. Specializing in state-of-the-art giant voice systems and outdoor warning sirens, [ATISystems.com](http://atisystems.com/) offers comprehensive solutions tailored to meet your safety requirements. What's Available at [ATISystems.com](http://atisystems.com/)? 1. Giant Voice Systems [ATISystems.com](http://atisystems.com/) stands out in the industry by providing robust giant voice systems designed to effectively broadcast emergency messages across expansive outdoor areas. These systems play a crucial role in emergency preparedness, facilitating clear and immediate communication during critical situations. 2. Outdoor Warning Sirens Offering a range of outdoor warning sirens, [ATISystems.com](http://atisystems.com/) ensures that communities and facilities have access to resilient alerting mechanisms. These sirens are engineered to emit high-decibel warnings, alerting individuals outdoors to potential threats or emergencies, thus enhancing overall safety protocols. Why Opt for [ATISystems.com](http://atisystems.com/) for Your Safety Solutions? 1. Cutting-Edge Technology [ATISystems.com](http://atisystems.com/) leverages cutting-edge technology in the development and deployment of their giant voice systems and outdoor warning sirens. The integration of advanced features ensures reliability and effectiveness precisely when it matters most. 2. Tailored Solutions Recognizing the uniqueness of each location and scenario, [ATISystems.com](http://atisystems.com/) offers customized solutions to match specific safety requirements. Whether for municipalities, industrial sites, or educational campuses, their systems can be tailored for optimal performance. 3. Dedication to Safety At the heart of [ATISystems.com](http://atisystems.com/) lies an unwavering commitment to safety. Their solutions are engineered to offer peace of mind, enabling swift and efficient communication during emergencies, thereby minimizing potential risks. Discover Unmatched Safety Solutions at [ATISystems.com](http://atisystems.com/) The dedication of [ATISystems.com](http://atisystems.com/) in delivering top-tier giant voice systems and outdoor warning sirens positions them as the go-to resource for enhancing outdoor safety measures. Their comprehensive range of products and services equips you with the necessary tools to mitigate risks and safeguard lives. Secure Your Environment Today Explore the cutting-edge solutions offered by [ATISystems.com](http://atisystems.com/) and take essential steps to fortify safety in your outdoor spaces. Delve into their giant voice systems and outdoor warning sirens to enhance your emergency preparedness. For more information, please visit: [Giant Voice System]([https://atisystems.com](https://atisystems.com/)), [Outdoor Warning System]([https://atisystems.com](https://atisystems.com/)), [Outdoor Warning Siren]([https://atisystems.com](https://atisystems.com/)) Visit [[ATISystems.com](http://atisystems.com/)]([https://atisystems.com](https://atisystems.com/)) today and empower your organization or community with reliable and effective safety solutions. With [ATISystems.com](http://atisystems.com/), safety is priority. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ihabmohsen at proton.me Tue Dec 5 11:59:49 2023 From: ihabmohsen at proton.me (Ihab Mohsen) Date: Tue, 05 Dec 2023 11:59:49 +0000 Subject: [Haskell-cafe] Why Choose Digitology.co as Your Digital Marketing Agency in Egypt Message-ID: Looking for an exceptional [digital marketing agency in Egypt](https://digitology.co)? Look no further than [Digitology.co](https://digitology.co)! Renowned as Egypt's premier [digital marketing agency](https://digitology.co), we specialize in enhancing online presence and fostering unparalleled success for your business. What Sets [Digitology.co](https://digitology.co) Apart as Egypt's Best [Digital Marketing Agency](https://digitology.co)? 1. Unmatched Expertise in [Digital Marketing](https://digitology.co) At [Digitology.co](https://digitology.co), our team comprises seasoned professionals excelling in various digital marketing facets. From tailored [SEO strategies for the Egyptian market](https://digitology.co) to impactful social media campaigns, our experts craft personalized solutions to meet your unique business needs. 2. Proven Track Record of Success As Egypt's [top digital marketing agency](https://digitology.co), our consistent delivery of outstanding results speaks volumes. We've significantly enhanced visibility, traffic, and conversions for numerous clients. Our success stories testify to our unwavering commitment to excellence. 3. Comprehensive [SEO and Online Marketing](https://digitology.co) Approach Understanding the importance of a holistic approach, our strategies encompass diverse techniques like content optimization, link building, and technical SEO. This ensures prominent search engine rankings for your website. Why [Digitology.co](https://digitology.co) Stands Out Among Egypt's [SEO Agencies](https://digitology.co) As a leading [SEO agency in Egypt](https://digitology.co), we prioritize driving organic growth and maximizing online presence. Our tailored strategies aim to improve website visibility, increase organic traffic, and enhance conversions by resonating with Egyptian audiences. Choose [Digitology.co](https://digitology.co) for Unparalleled [Digital Marketing Solutions](https://digitology.co) Partnering with us grants access to cutting-edge strategies, personalized solutions, and a dedicated team committed to your success. We aim to propel your business to new heights through innovative, results-oriented digital marketing strategies. Take the Next Step Towards Success Ready to elevate your digital presence? Partner with [Digitology.co](https://digitology.co), Egypt's [best digital marketing agency](https://digitology.co). Contact us today to explore how our tailored solutions can revolutionize your online presence and drive tangible business growth. Explore [Digitology.co](https://digitology.co)'s services and witness firsthand how we transform your digital marketing endeavors. At [Digitology.co](https://digitology.co), your success is our priority! For more info, visit the best digital marketing agency in Egypt [here](https://digitology.co) -------------- next part -------------- An HTML attachment was scrubbed... URL: From ivanperezdominguez at gmail.com Tue Dec 5 17:04:49 2023 From: ivanperezdominguez at gmail.com (Ivan Perez) Date: Tue, 5 Dec 2023 09:04:49 -0800 Subject: [Haskell-cafe] Why Choose Digitology.co as Your Digital Marketing Agency in Egypt In-Reply-To: References: Message-ID: Can an admin please ban this person? Ivan On Tue, 5 Dec 2023 at 04:01, Ihab Mohsen via Haskell-Cafe < haskell-cafe at haskell.org> wrote: > Looking for an exceptional [digital marketing agency in Egypt]( > https://digitology.co)? Look no further than [Digitology.co]( > https://digitology.co)! Renowned as Egypt's premier [digital marketing > agency](https://digitology.co), we specialize in enhancing online > presence and fostering unparalleled success for your business. > > > > What Sets [Digitology.co](https://digitology.co) Apart as Egypt's Best > [Digital Marketing Agency](https://digitology.co)? > > > > 1. Unmatched Expertise in [Digital Marketing](https://digitology.co) > > > > At [Digitology.co](https://digitology.co), our team comprises seasoned > professionals excelling in various digital marketing facets. From tailored > [SEO strategies for the Egyptian market](https://digitology.co) to > impactful social media campaigns, our experts craft personalized solutions > to meet your unique business needs. > > > > 2. Proven Track Record of Success > > > > As Egypt's [top digital marketing agency](https://digitology.co), our > consistent delivery of outstanding results speaks volumes. We've > significantly enhanced visibility, traffic, and conversions for numerous > clients. Our success stories testify to our unwavering commitment to > excellence. > > > > 3. Comprehensive [SEO and Online Marketing](https://digitology.co) > Approach > > > > Understanding the importance of a holistic approach, our strategies > encompass diverse techniques like content optimization, link building, and > technical SEO. This ensures prominent search engine rankings for your > website. > > > > Why [Digitology.co](https://digitology.co) Stands Out Among Egypt's [SEO > Agencies](https://digitology.co) > > > > As a leading [SEO agency in Egypt](https://digitology.co), we prioritize > driving organic growth and maximizing online presence. Our tailored > strategies aim to improve website visibility, increase organic traffic, and > enhance conversions by resonating with Egyptian audiences. > > > > Choose [Digitology.co](https://digitology.co) for Unparalleled [Digital > Marketing Solutions](https://digitology.co) > > > > Partnering with us grants access to cutting-edge strategies, personalized > solutions, and a dedicated team committed to your success. We aim to propel > your business to new heights through innovative, results-oriented digital > marketing strategies. > > > > Take the Next Step Towards Success > > > > Ready to elevate your digital presence? Partner with [Digitology.co]( > https://digitology.co), Egypt's [best digital marketing agency]( > https://digitology.co). Contact us today to explore how our tailored > solutions can revolutionize your online presence and drive tangible > business growth. Explore [Digitology.co](https://digitology.co)'s > services and witness firsthand how we transform your digital marketing > endeavors. At [Digitology.co](https://digitology.co), your success is our > priority! > > > > For more info, visit the best digital marketing agency in Egypt [here]( > https://digitology.co) > _______________________________________________ > 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 tom-lists-haskell-cafe-2023 at jaguarpaw.co.uk Tue Dec 5 17:45:21 2023 From: tom-lists-haskell-cafe-2023 at jaguarpaw.co.uk (Tom Ellis) Date: Tue, 5 Dec 2023 17:45:21 +0000 Subject: [Haskell-cafe] Why Choose Digitology.co as Your Digital Marketing Agency in Egypt In-Reply-To: References: Message-ID: Yes, agreed, please. On Tue, Dec 05, 2023 at 09:04:49AM -0800, Ivan Perez wrote: > Can an admin please ban this person? > > On Tue, 5 Dec 2023 at 04:01, Ihab Mohsen via Haskell-Cafe < > haskell-cafe at haskell.org> wrote: > > > Looking for an exceptional [digital marketing agency in Egypt]( > > https://digitology.co)? Look no further than [Digitology.co]( > > https://digitology.co)! Renowned as Egypt's premier [digital marketing > > agency](https://digitology.co), we specialize in enhancing online > > presence and fostering unparalleled success for your business. > > > > > > > > What Sets [Digitology.co](https://digitology.co) Apart as Egypt's Best > > [Digital Marketing Agency](https://digitology.co)? > > > > > > > > 1. Unmatched Expertise in [Digital Marketing](https://digitology.co) > > > > > > > > At [Digitology.co](https://digitology.co), our team comprises seasoned > > professionals excelling in various digital marketing facets. From tailored > > [SEO strategies for the Egyptian market](https://digitology.co) to > > impactful social media campaigns, our experts craft personalized solutions > > to meet your unique business needs. > > > > > > > > 2. Proven Track Record of Success > > > > > > > > As Egypt's [top digital marketing agency](https://digitology.co), our > > consistent delivery of outstanding results speaks volumes. We've > > significantly enhanced visibility, traffic, and conversions for numerous > > clients. Our success stories testify to our unwavering commitment to > > excellence. > > > > > > > > 3. Comprehensive [SEO and Online Marketing](https://digitology.co) > > Approach > > > > > > > > Understanding the importance of a holistic approach, our strategies > > encompass diverse techniques like content optimization, link building, and > > technical SEO. This ensures prominent search engine rankings for your > > website. > > > > > > > > Why [Digitology.co](https://digitology.co) Stands Out Among Egypt's [SEO > > Agencies](https://digitology.co) > > > > > > > > As a leading [SEO agency in Egypt](https://digitology.co), we prioritize > > driving organic growth and maximizing online presence. Our tailored > > strategies aim to improve website visibility, increase organic traffic, and > > enhance conversions by resonating with Egyptian audiences. > > > > > > > > Choose [Digitology.co](https://digitology.co) for Unparalleled [Digital > > Marketing Solutions](https://digitology.co) > > > > > > > > Partnering with us grants access to cutting-edge strategies, personalized > > solutions, and a dedicated team committed to your success. We aim to propel > > your business to new heights through innovative, results-oriented digital > > marketing strategies. > > > > > > > > Take the Next Step Towards Success > > > > > > > > Ready to elevate your digital presence? Partner with [Digitology.co]( > > https://digitology.co), Egypt's [best digital marketing agency]( > > https://digitology.co). Contact us today to explore how our tailored > > solutions can revolutionize your online presence and drive tangible > > business growth. Explore [Digitology.co](https://digitology.co)'s > > services and witness firsthand how we transform your digital marketing > > endeavors. At [Digitology.co](https://digitology.co), your success is our > > priority! From harendra.kumar at gmail.com Tue Dec 5 17:50:12 2023 From: harendra.kumar at gmail.com (Harendra Kumar) Date: Tue, 5 Dec 2023 23:20:12 +0530 Subject: [Haskell-cafe] Download stats not updated on Hackage Message-ID: Hi, It seems the download count for packages on Hackage is stuck for quite some time now. Is this issue known to the Hackage maintainers? -harendra From ida.bzowska at gmail.com Tue Dec 5 18:18:10 2023 From: ida.bzowska at gmail.com (Ida Bzo) Date: Tue, 5 Dec 2023 19:18:10 +0100 Subject: [Haskell-cafe] Haskell.org Call for Nominations (for the terms 2024-2027) Message-ID: Dear Haskellers, We are pleased to announce that nominations are now open for the Haskell.org committee. You can nominate yourself or a friend for a three-year term (2024-2027) by sending an email to [committee at haskell.org] by January 10, 2024. Self-nominations and re-nominations are also welcome. Please include any relevant information about yourself or your nominee that you think will help us make our decision. Committee members do not have to be technical experts in Haskell. We are looking for people who are enthusiastic about improving the Haskell community and come from a variety of backgrounds, such as academia, industry, open-source development, and community building. Our goal is to represent the various facets of the Haskell world, including gender, race, location, and industry or research. The committee's responsibilities include setting policies, providing guidance for Haskell.org infrastructure, planning for the long term, and being fiscally responsible with Haskell.org funds and donations. Being a committee member does not require a significant amount of time, but members should be responsive during discussions and should be able to attend monthly calls and participate in the Haskell.org Slack and mailing lists. Candidates for the committee should possess strong leadership, communication, and judgment skills. They must be able to set aside personal or business-related biases and make decisions with the good of the open-source Haskell community in mind. For more information about the committee's roles and responsibilities, please visit https://www.haskell.org/haskell-org-committee/ If you have any questions about the nomination process, please feel free to email us at [committee at haskell.org], or contact one of us individually. λCheers, Ida Bzo -------------- next part -------------- An HTML attachment was scrubbed... URL: From lc985 at cam.ac.uk Fri Dec 8 11:39:58 2023 From: lc985 at cam.ac.uk (L. Cicolini) Date: Fri, 8 Dec 2023 11:39:58 +0000 Subject: [Haskell-cafe] CGO'24 - Student Research Competition (SRC) and more Message-ID: Dear all, The International Symposium on Code Generation and Optimization (CGO) is hosting a Student Research Competition (SRC). Our SRC is a unique opportunity for undergraduate and graduate students to present their original research before a panel of judges and attendees at CGO'24. The winner will be invited to the Grand 2024 ACM SRC competition. If you are an undergraduate or postgraduate student doing research in compiler-related topics, consider applying. We look forward to meeting you! CGO'24 is a compiler conference happening in Edinburgh, March 2nd to 6th 2024. This conference is a great opportunity for anyone interested in compilers to connect with great researchers and professionals and will host four existing workshops: LLVM [1], the BuildIt Framework [2], LATHC [3], and C4ML [4]. Find more information on https://conf.researchr.org/home/cgo-2024 and share this message with anyone who might be interested! Best, Luisa Cicolini [1] LLVM Performance Workshop: https://llvm.org/devmtg/2024-03/ [2] BuildIt: Building DSLs made easy with the BuildIt Framework: https://buildit.so/tutorial/ [3] LATHC: Languages, Architectures, and Tools for Heterogeneous Computing Workshop: https://jnamaral.github.io/LATHC24/ [4] C4ML - Compilers For Machine Learning: https://www.c4ml.org/c4ml-2024 -------------- next part -------------- An HTML attachment was scrubbed... URL: From ulidtko at gmail.com Fri Dec 8 15:50:58 2023 From: ulidtko at gmail.com (Max Ulidtko) Date: Fri, 08 Dec 2023 16:50:58 +0100 Subject: [Haskell-cafe] OverloadedStrings, but with compile-time invariants Message-ID: Greetings @cafe, Transparent wrapping of string literals into custom types, driven automatically by type inference, is of course very useful. I'm getting huge mileage off GHC's OverloadedStrings when working with e.g. the Text type: class IsString a where fromString :: String -> a instance IsString Text {- ... -} greeting :: Text greeting = "Hello" But I hope there's possibly room for improvement. I've got a bag of several use-cases; perhaps the simplest is the following. Consider a type called NonEmptyText which is a (wrapper around) Text, but with an added invariant that the contained text is never the empty string "". Depending on codebase, such a type can be very useful too, allowing to offload the burden of keeping track of the invariant onto machine; the typechecker will show me all the spots to handle, current or future ones. IOW, this type enables writing a non-boolean-blind null check, toNonEmptyText :: ToText str => str -> Maybe NonEmptyText — which makes not only the programmer, but also the compiler, aware of the null-check result. I'm focusing the example on Text to somewhat maintain generality of the idea. NonEmpty Char can be an alternative formulation of "non-empty String"; length-indexed vectors could possibly handle this too. But there're all sorts of invariants besides non-emptiness one may wish to express. I'll omit other examples; but to summarize, I've got plenty of practical motivation to get "smart literals". And to the point: IsString as it stands, forces us to write much unsatisfactory instances: instance IsString NonEmptyText where fromString (c:cs) = NonEmptyText.new c cs fromString [] = error "unavoidable runtime panic" -- argh ... despite fromString being invoked, presumably with OverloadedStrings, on a string literal — which is statically known at compile-time. I'd imagine upgrading the interface with GHC's own TypeLits: class KnownSymbol lit => IsString' str lit where fromString' :: proxy lit -> str This 2-parameter formulation of IsString enables pretty straightforward user code, along the lines of: type family MyInvariant (s :: Symbol) :: Constraint where MyInvariant "" = TypeError ('Text "Empty string literal") MyInvariant _s = () instance (MyInvariant lit, KnownSymbol lit) => IsString' NonEmptyText lit where fromString' = nothingImpossible . NeT.fromText . toText . symbolVal where nothingImpossible (Just x) = x nothingImpossible Nothing = error "typelevel invariant violated" text1, text2 :: NonEmptyText text1 = fromString' $ Proxy @"hello, types" text2 = fromString' $ Proxy @"" -- compile error here, as expected! With the primes, this is possible to write today. With AllowAmbiguousTypes, the unwieldy syntax can be abbreviated somewhat, e.g. smartLiteral @"overloaded string literal with compiler-checked invariant" — but is still rather awkward... in the same way that ubiquitous T.pack is annoying enough to want to enable OverloadedStrings and stop seeing it all over the place. The question is, could this IsString' somehow become the IsString that OverloadedStrings is friends with? I guess, not soon, with compatibility in mind... But in principle? Is it even worth trying to pursue the GHC Proposal path? Perhaps a new extension OverloadedTypelevelStrings? Relatedly... Can a GHC Plugin do this? And overall, to zoom out of "XY Problem" pitfalls: am I missing a neater way to have "partial" IsString instances, those that can reject some literals at compile-time? Having this code work is the goal: text1, text2 :: NonEmptyText text1 = "hello, types" text2 = "" -- compile error Best regards, Max -------------- next part -------------- An HTML attachment was scrubbed... URL: From oleg.grenrus at iki.fi Fri Dec 8 15:54:53 2023 From: oleg.grenrus at iki.fi (Oleg Grenrus) Date: Fri, 8 Dec 2023 17:54:53 +0200 Subject: [Haskell-cafe] OverloadedStrings, but with compile-time invariants In-Reply-To: References: Message-ID: Can a ghc-plugin do that? Yes, see https://hackage.haskell.org/package/overloaded-0.3.1/docs/Overloaded-Symbols.html - Oleg On 8.12.2023 17.50, Max Ulidtko wrote: > Greetings @cafe, > > Transparent wrapping of string literals into custom types, driven > automatically by type inference, is of course very useful. I'm getting > huge mileage off GHC's OverloadedStrings when working with e.g. the > Text type: > > class IsString a where > fromString :: String -> a > instance IsString Text {- ... -} > greeting :: Text > greeting = "Hello" > > But I hope there's possibly room for improvement. I've got a bag of > several use-cases; perhaps the simplest is the following. > > Consider a type called NonEmptyText which is a (wrapper around) Text, > but with an added invariant that the contained text is never the empty > string "". > > Depending on codebase, such a type can be very useful too, allowing to > offload the burden of keeping track of the invariant onto machine; the > typechecker will show me all the spots to handle, current or future > ones. IOW, this type enables writing a non-boolean-blind null check, > toNonEmptyText :: ToText str => str -> Maybe NonEmptyText — which > makes not only the programmer, but also the compiler, aware of the > null-check result. > > I'm focusing the example on Text to somewhat maintain generality of > the idea. NonEmpty Char can be an alternative formulation of > "non-empty String"; length-indexed vectors could possibly handle this > too. But there're all sorts of invariants besides non-emptiness one > may wish to express. > > I'll omit other examples; but to summarize, I've got plenty of > practical motivation to get "smart literals". > > And to the point: IsString as it stands, forces us to write much > unsatisfactory instances: > > instance IsString NonEmptyText where > fromString (c:cs) = NonEmptyText.new c cs > fromString [] = error "unavoidable runtime panic" -- argh > > ... despite fromString being invoked, presumably with > OverloadedStrings, on a string literal — which is statically known at > compile-time. > > I'd imagine upgrading the interface with GHC's own TypeLits: > > class KnownSymbol lit => IsString' str lit where > fromString' :: proxy lit -> str > This 2-parameter formulation of IsString enables pretty > straightforward user code, along the lines of: > > type family MyInvariant (s :: Symbol) :: Constraint where >   MyInvariant "" = TypeError ('Text "Empty string literal") >   MyInvariant _s = () > > instance (MyInvariant lit, KnownSymbol lit) => IsString' NonEmptyText > lit where >   fromString' = nothingImpossible . NeT.fromText . toText . symbolVal > where >     nothingImpossible (Just x) = x >     nothingImpossible Nothing = error "typelevel invariant violated" > > text1, text2 :: NonEmptyText > text1 = fromString' $ Proxy @"hello, types" > text2 = fromString' $ Proxy @""        -- compile error here, as expected! > > With the primes, this is possible to write today. With > AllowAmbiguousTypes, the unwieldy syntax can be abbreviated somewhat, > e.g. smartLiteral @"overloaded string literal with compiler-checked > invariant" — but is still rather awkward... in the same way that > ubiquitous T.pack is annoying enough to want to enable > OverloadedStrings and stop seeing it all over the place. > > The question is, could this IsString' somehow become the IsString that > OverloadedStrings is friends with? > I guess, not soon, with compatibility in mind... But in principle? Is > it even worth trying to pursue the GHC Proposal path? > Perhaps a new extension OverloadedTypelevelStrings? > > Relatedly... Can a GHC Plugin do this? > > And overall, to zoom out of "XY Problem" pitfalls: am I missing a > neater way to have "partial" IsString instances, those that can reject > some literals at compile-time? > > Having this code work is the goal: > > text1, text2 :: NonEmptyText > text1 = "hello, types" > text2 = "" -- compile error > > Best regards, > Max > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From lemming at henning-thielemann.de Fri Dec 8 16:08:53 2023 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Fri, 8 Dec 2023 17:08:53 +0100 (CET) Subject: [Haskell-cafe] OverloadedStrings, but with compile-time invariants In-Reply-To: References: Message-ID: On Fri, 8 Dec 2023, Max Ulidtko wrote: > Consider a type called NonEmptyText which is a (wrapper around) Text, > but with an added invariant that the contained text is never the empty > string "". Maybe that is too much to expect from a string literal syntax? I have no convincing solution for your string example, but I got a nice one for general (non-Char) non-empty lists. Analogous to your example you might ask for overloaded list syntax for NonEmpty lists. We are so used to the list syntax with comma separation, that we have mostly forgotten about the list constructor (:). Instead of [1,2,3] we could write 1:2:3:[]. With this syntax it is also easy to write a type checked NonEmpty list this way: 1:|2:3:[]. With my non-empty package you can even write lists with any required minimum number of elements, like 1!:2!:3:4:5:[]. https://wiki.haskell.org/List_notation From ietf-dane at dukhovni.org Fri Dec 8 19:12:46 2023 From: ietf-dane at dukhovni.org (Viktor Dukhovni) Date: Fri, 8 Dec 2023 14:12:46 -0500 Subject: [Haskell-cafe] OverloadedStrings, but with compile-time invariants In-Reply-To: References: Message-ID: On Fri, Dec 08, 2023 at 04:50:58PM +0100, Max Ulidtko wrote: > And overall, to zoom out of "XY Problem" pitfalls: am I missing a neater way > to have "partial" IsString instances, those that can reject some literals at > compile-time? > > Having this code work is the goal: > > text1, text2 :: NonEmptyText > text1 = "hello, types" > text2 = "" -- compile error Is at TH splice too cumbersome? text1, text2 :: NonEmptyText text1 = $$(neTxt "hello, types") text = $$(neTxt "") -- compile error I am validating DNS domain name literals at compile time, where checks include full DNS syntax validation with no empty labels, no labels longer than 63 bytes, and overall wire length at most 255 bytes. https://github.com/dnsbase/dnsbase/blob/548270f2e575949592ca3f1e40c58edc450bd0c3/internal/Net/DNSBase/Internal/Domain.hs#L249-L267 -- Viktor. From allbery.b at gmail.com Fri Dec 8 19:16:01 2023 From: allbery.b at gmail.com (Brandon Allbery) Date: Fri, 8 Dec 2023 14:16:01 -0500 Subject: [Haskell-cafe] OverloadedStrings, but with compile-time invariants In-Reply-To: References: Message-ID: Might https://hackage.haskell.org/package/validated-literals be of interest? On Fri, Dec 8, 2023 at 2:13 PM Viktor Dukhovni wrote: > On Fri, Dec 08, 2023 at 04:50:58PM +0100, Max Ulidtko wrote: > > > And overall, to zoom out of "XY Problem" pitfalls: am I missing a neater > way > > to have "partial" IsString instances, those that can reject some > literals at > > compile-time? > > > > Having this code work is the goal: > > > > text1, text2 :: NonEmptyText > > text1 = "hello, types" > > text2 = "" -- compile error > > Is at TH splice too cumbersome? > > text1, text2 :: NonEmptyText > text1 = $$(neTxt "hello, types") > text = $$(neTxt "") -- compile error > > I am validating DNS domain name literals at compile time, where checks > include full DNS syntax validation with no empty labels, no labels > longer than 63 bytes, and overall wire length at most 255 bytes. > > > https://github.com/dnsbase/dnsbase/blob/548270f2e575949592ca3f1e40c58edc450bd0c3/internal/Net/DNSBase/Internal/Domain.hs#L249-L267 > > -- > 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. -- brandon s allbery kf8nh allbery.b at gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From adam at well-typed.com Fri Dec 8 20:31:37 2023 From: adam at well-typed.com (Adam Gundry) Date: Fri, 8 Dec 2023 20:31:37 +0000 Subject: [Haskell-cafe] OverloadedStrings, but with compile-time invariants In-Reply-To: References: Message-ID: Hi Max, Since GHC 9.6 you can do this with OverloadedLabels, at the minor syntactic cost of a prefix # on the literal. For example: {-# LANGUAGE DataKinds #-} {-# LANGUAGE OverloadedLabels #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} import Data.Kind import Data.Proxy import GHC.OverloadedLabels import GHC.TypeError import GHC.TypeLits newtype NonEmptyString = NonEmptyString String type family MyInvariant (s :: Symbol) :: Constraint where MyInvariant "" = Unsatisfiable ('Text "Empty string literal") MyInvariant _s = () instance (MyInvariant lit, KnownSymbol lit) => IsLabel lit NonEmptyString where fromLabel = NonEmptyString (symbolVal (Proxy @lit)) good, bad :: NonEmptyString good = #"A b c" bad = #"" {- • Empty string literal • In the expression: #"" :: NonEmptyString In an equation for ‘bad’: bad = #"" :: NonEmptyString -} More details are in the proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst Cheers, Adam On 08/12/2023 15:50, Max Ulidtko wrote: > Greetings @cafe, > > Transparent wrapping of string literals into custom types, driven > automatically by type inference, is of course very useful. I'm getting > huge mileage off GHC's OverloadedStrings when working with e.g. the Text > type: > > class IsString a where > fromString :: String -> a > > > instance IsString Text {- ... -} > > > greeting :: Text > > greeting = "Hello" > > > But I hope there's possibly room for improvement. I've got a bag of > several use-cases; perhaps the simplest is the following. > > Consider a type called NonEmptyText which is a (wrapper around) Text, > but with an added invariant that the contained text is never the empty > string "". > > Depending on codebase, such a type can be very useful too, allowing to > offload the burden of keeping track of the invariant onto machine; the > typechecker will show me all the spots to handle, current or future > ones. IOW, this type enables writing a non-boolean-blind null check, > toNonEmptyText :: ToText str => str -> Maybe NonEmptyText — which makes > not only the programmer, but also the compiler, aware of the null-check > result. > > I'm focusing the example on Text to somewhat maintain generality of the > idea. NonEmpty Char can be an alternative formulation of "non-empty > String"; length-indexed vectors could possibly handle this too. But > there're all sorts of invariants besides non-emptiness one may wish to > express. > > I'll omit other examples; but to summarize, I've got plenty of practical > motivation to get "smart literals". > > And to the point: IsString as it stands, forces us to write much > unsatisfactory instances: > > instance IsString NonEmptyText where > > fromString (c:cs) = NonEmptyText.new c cs > > fromString [] = error "unavoidable runtime panic" -- argh > > > ... despite fromString being invoked, presumably with OverloadedStrings, > on a string literal — which is statically known at compile-time. > > I'd imagine upgrading the interface with GHC's own TypeLits: > > class KnownSymbol lit => IsString' str lit where > > fromString' :: proxy lit -> str > > > This 2-parameter formulation of IsString enables pretty straightforward > user code, along the lines of: > > type family MyInvariant (s :: Symbol) :: Constraint where >   MyInvariant "" = TypeError ('Text "Empty string literal") >   MyInvariant _s = () > > instance (MyInvariant lit, KnownSymbol lit) => IsString' NonEmptyText > lit where >   fromString' = nothingImpossible . NeT.fromText . toText . symbolVal where >     nothingImpossible (Just x) = x >     nothingImpossible Nothing = error "typelevel invariant violated" > > text1, text2 :: NonEmptyText > text1 = fromString' $ Proxy @"hello, types" > text2 = fromString' $ Proxy @""            -- compile error here, as > expected! > > With the primes, this is possible to write today. With > AllowAmbiguousTypes, the unwieldy syntax can be abbreviated somewhat, > e.g. smartLiteral @"overloaded string literal with compiler-checked > invariant" — but is still rather awkward... in the same way that > ubiquitous T.pack is annoying enough to want to enable OverloadedStrings > and stop seeing it all over the place. > > The question is, could this IsString' somehow become the IsString that > OverloadedStrings is friends with? > I guess, not soon, with compatibility in mind... But in principle? Is it > even worth trying to pursue the GHC Proposal path? > Perhaps a new extension OverloadedTypelevelStrings? > > Relatedly... Can a GHC Plugin do this? > > And overall, to zoom out of "XY Problem" pitfalls: am I missing a neater > way to have "partial" IsString instances, those that can reject some > literals at compile-time? > > Having this code work is the goal: > > text1, text2 :: NonEmptyText > text1 = "hello, types" > text2 = "" -- compile error > > Best regards, > Max -- Adam Gundry, Haskell Consultant Well-Typed LLP, https://www.well-typed.com/ Registered in England & Wales, OC335890 27 Old Gloucester Street, London WC1N 3AX, England From xnningxie at gmail.com Fri Dec 8 21:49:30 2023 From: xnningxie at gmail.com (Ningning Xie) Date: Fri, 8 Dec 2023 16:49:30 -0500 Subject: [Haskell-cafe] PLDI'24 Artifact Evaluation Committee: Call for nominations Message-ID: Dear all, We are looking for motivated students and researchers to be members of the PLDI 2024 Artifact Evaluation Committee (AEC). The artifact evaluation process aims to promote, share and catalog the research artifacts of papers accepted to the PLDI research track. This year, we are accepting self-nominations for the AEC. The self-nomination form is available at: https://forms.gle/wWGfW33qMY2gUqqz7 The first round of nomination ends on Dec 22nd, 2023. As a committee member, the primary responsibilities would be to review the artifacts submitted corresponding to the already accepted papers in the main research track. In particular, you may have to run the associated tool, check whether the results in the main paper can be reproduced, and inspect the data. We expect the bulk of the review work to take place between early February and mid April. Each artifact will take about 8h to review, and reviewers will be assigned about 3 artifacts to review. Come join us in improving the quality of research in our field! Best regards, Manuel Rigger and Ningning Xie -------------- next part -------------- An HTML attachment was scrubbed... URL: From anton.kholomiov at gmail.com Sun Dec 10 11:21:32 2023 From: anton.kholomiov at gmail.com (Anton Kholomiov) Date: Sun, 10 Dec 2023 14:21:32 +0300 Subject: [Haskell-cafe] [ANN] mig-2.1 minimal server library Message-ID: I'm happy to announce a new release of the mig library. It's a minimal and simple library to build servers. This release adds some goodies for servers that produce HTML: * cookies (new [input Cookie]( https://hackage.haskell.org/package/mig-0.2.1.0/docs/Mig-Core-Types-Route.html#t:Cookie) type and [function to set]( https://hackage.haskell.org/package/mig-0.2.1.0/docs/Mig-Core-Class-Response.html#v:setCookie) the cookies) * [type-safe stable URLs]( https://hackage.haskell.org/package/mig-0.2.1.0/docs/Mig-Core-Class-Url.html) from server definition * an example [HtmlTemplate]( https://github.com/anton-k/mig/tree/main/examples/mig-example-apps/HtmlTemplate) on how to use template engine and type-safe URLs with the library Also it adds a stack template to create new hello-world server with stack (on how to use it see the section on how to start [a new mig project]( https://anton-k.github.io/mig/#how-to-start-a-new-project) in the tutorial). Links: * [github](https://github.com/anton-k/mig) * [tutorial](https://anton-k.github.io/mig/) * [hackage for the server library]( https://hackage.haskell.org/package/mig-server) * [hackage for the core library](https://hackage.haskell.org/package/mig) * [examples]( https://github.com/anton-k/mig/tree/main/examples/mig-example-apps#mig-example-apps ) -------------- next part -------------- An HTML attachment was scrubbed... URL: From brown.m at pm.me Sun Dec 10 20:50:07 2023 From: brown.m at pm.me (Melanie Brown) Date: Sun, 10 Dec 2023 20:50:07 +0000 Subject: [Haskell-cafe] OverloadedStrings, but with compile-time invariants In-Reply-To: References: Message-ID: <5EqYhfbLXl4jYxccp2raDrRzOm7EOtV1M5SzpSuUaqrRabj1rXdTjqtz5pc55KAkiWpyEoDO8woZANf2JVGWwsp5WpyZqZ_OsJ4txItFl_M=@pm.me> You can achieve this with Template Haskell in multiple ways; one mentioned already by Viktor with $$(splices), and another way with [special|quasiquotes|]. A quasiquoter [1] (in this example, “special”) lets you specify the way its body (the stuff between the separators) gets translated into source code by the compiler with complex intermediate steps like parsing and interpolation. An excellent example of the strength of quasiquoters is the shakespeare library [2] used by Yesod: though it is mainly for HTML/CSS/JS templating, I often use the “st” quasiquoter instead of -XOverloadedStrings to get around ambiguity errors. I’ve made my own quasiquoter imitating the Yesod library for interpolating Haskell values into raw SQL code following those examples. I think it would be fairly simple to write one for a NonEmptyText type, especially if you don’t need variable interpolation. [1] https://hackage.haskell.org/package/template-haskell-2.21.0.0/docs/Language-Haskell-TH-Quote.html#t:QuasiQuoter [2] https://hackage.haskell.org/package/shakespeare Cheers Melanie Brown On Fri, Dec 8, 2023 at 15:31, Adam Gundry <[adam at well-typed.com](mailto:On Fri, Dec 8, 2023 at 15:31, Adam Gundry < wrote: > Hi Max, > > Since GHC 9.6 you can do this with OverloadedLabels, at the minor > syntactic cost of a prefix # on the literal. For example: > > {-# LANGUAGE DataKinds #-} > {-# LANGUAGE OverloadedLabels #-} > {-# LANGUAGE TypeFamilies #-} > {-# LANGUAGE UndecidableInstances #-} > > import Data.Kind > import Data.Proxy > import GHC.OverloadedLabels > import GHC.TypeError > import GHC.TypeLits > > newtype NonEmptyString = NonEmptyString String > > type family MyInvariant (s :: Symbol) :: Constraint where > MyInvariant "" = Unsatisfiable ('Text "Empty string literal") > MyInvariant _s = () > > instance (MyInvariant lit, KnownSymbol lit) > => IsLabel lit NonEmptyString where > fromLabel = NonEmptyString (symbolVal (Proxy @lit)) > > good, bad :: NonEmptyString > good = #"A b c" > bad = #"" > {- > • Empty string literal > • In the expression: #"" :: NonEmptyString > In an equation for ‘bad’: bad = #"" :: NonEmptyString > -} > > More details are in the proposal: > https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst > > Cheers, > > Adam > > On 08/12/2023 15:50, Max Ulidtko wrote: >> Greetings @cafe, >> >> Transparent wrapping of string literals into custom types, driven >> automatically by type inference, is of course very useful. I'm getting >> huge mileage off GHC's OverloadedStrings when working with e.g. the Text >> type: >> >> class IsString a where >> fromString :: String -> a >> >> >> instance IsString Text {- ... -} >> >> >> greeting :: Text >> >> greeting = "Hello" >> >> >> But I hope there's possibly room for improvement. I've got a bag of >> several use-cases; perhaps the simplest is the following. >> >> Consider a type called NonEmptyText which is a (wrapper around) Text, >> but with an added invariant that the contained text is never the empty >> string "". >> >> Depending on codebase, such a type can be very useful too, allowing to >> offload the burden of keeping track of the invariant onto machine; the >> typechecker will show me all the spots to handle, current or future >> ones. IOW, this type enables writing a non-boolean-blind null check, >> toNonEmptyText :: ToText str => str -> Maybe NonEmptyText — which makes >> not only the programmer, but also the compiler, aware of the null-check >> result. >> >> I'm focusing the example on Text to somewhat maintain generality of the >> idea. NonEmpty Char can be an alternative formulation of "non-empty >> String"; length-indexed vectors could possibly handle this too. But >> there're all sorts of invariants besides non-emptiness one may wish to >> express. >> >> I'll omit other examples; but to summarize, I've got plenty of practical >> motivation to get "smart literals". >> >> And to the point: IsString as it stands, forces us to write much >> unsatisfactory instances: >> >> instance IsString NonEmptyText where >> >> fromString (c:cs) = NonEmptyText.new c cs >> >> fromString [] = error "unavoidable runtime panic" -- argh >> >> >> ... despite fromString being invoked, presumably with OverloadedStrings, >> on a string literal — which is statically known at compile-time. >> >> I'd imagine upgrading the interface with GHC's own TypeLits: >> >> class KnownSymbol lit => IsString' str lit where >> >> fromString' :: proxy lit -> str >> >> >> This 2-parameter formulation of IsString enables pretty straightforward >> user code, along the lines of: >> >> type family MyInvariant (s :: Symbol) :: Constraint where >> MyInvariant "" = TypeError ('Text "Empty string literal") >> MyInvariant _s = () >> >> instance (MyInvariant lit, KnownSymbol lit) => IsString' NonEmptyText >> lit where >> fromString' = nothingImpossible . NeT.fromText . toText . symbolVal where >> nothingImpossible (Just x) = x >> nothingImpossible Nothing = error "typelevel invariant violated" >> >> text1, text2 :: NonEmptyText >> text1 = fromString' $ Proxy @"hello, types" >> text2 = fromString' $ Proxy @"" -- compile error here, as >> expected! >> >> With the primes, this is possible to write today. With >> AllowAmbiguousTypes, the unwieldy syntax can be abbreviated somewhat, >> e.g. smartLiteral @"overloaded string literal with compiler-checked >> invariant" — but is still rather awkward... in the same way that >> ubiquitous T.pack is annoying enough to want to enable OverloadedStrings >> and stop seeing it all over the place. >> >> The question is, could this IsString' somehow become the IsString that >> OverloadedStrings is friends with? >> I guess, not soon, with compatibility in mind... But in principle? Is it >> even worth trying to pursue the GHC Proposal path? >> Perhaps a new extension OverloadedTypelevelStrings? >> >> Relatedly... Can a GHC Plugin do this? >> >> And overall, to zoom out of "XY Problem" pitfalls: am I missing a neater >> way to have "partial" IsString instances, those that can reject some >> literals at compile-time? >> >> Having this code work is the goal: >> >> text1, text2 :: NonEmptyText >> text1 = "hello, types" >> text2 = "" -- compile error >> >> Best regards, >> Max > > -- > Adam Gundry, Haskell Consultant > Well-Typed LLP, https://www.well-typed.com/ > > Registered in England & Wales, OC335890 > 27 Old Gloucester Street, London WC1N 3AX, England > > _______________________________________________ > 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 hecate at glitchbra.in Mon Dec 11 08:31:02 2023 From: hecate at glitchbra.in (=?UTF-8?Q?H=C3=A9cate?=) Date: Mon, 11 Dec 2023 09:31:02 +0100 Subject: [Haskell-cafe] Issues with static linking of a C ".a" library with cabal Message-ID: <4938d627-9528-4d4f-a8f4-1214fffaa057@glitchbra.in> Hi everyone, I'm hitting a number of roadblocks while trying to embed a ".a" file (and its headers) in Haskell code. The setup is the following: I have a bindings library that handles all of the cAPI FFI declarations, and a consumer that does not directly depend on the underlying C library. As such, I use a combination of extra-bundled-libraries, include-dirs and install-includes stanzas in my cabal file: elifflag(bundled-libsodium) extra-bundled-libraries: Csodium include-dirs: include install-includes: include/sodium.h include/sodium/core.h include/sodium/crypto_aead_aes256gcm.h […] (full file here: https://github.com/haskell-cryptography/libsodium-bindings/blob/37-libsodium-vendoring/libsodium-bindings/libsodium-bindings.cabal) It all seemed to work on my day-to-day system, but further tests on a system that did not have libsodium installed system-wide showed that there's still a missing part: |/usr/bin/ld.gold:error:cannotfind-lsodium collect2:error:ldreturned1exitstatus `gcc'failedinphase`Linker'.(Exitcode:1)| At this point I am simply baffled, because I thought that I had the right invocation for all of this to work. What else can I do? Am I missing something obvious? I have opened a ticket here with a bit more details: https://github.com/haskell/cabal/issues/9509 Cheers, Hécate -- Hécate ✨ 🐦: @TechnoEmpress IRC: Hecate WWW:https://glitchbra.in RUN: BSD -------------- next part -------------- An HTML attachment was scrubbed... URL: From icfp.publicity at googlemail.com Tue Dec 12 02:08:02 2023 From: icfp.publicity at googlemail.com (ICFP Publicity) Date: Tue, 12 Dec 2023 10:08:02 +0800 Subject: [Haskell-cafe] ICFP 2024: Call for Workshops and Co-Located Events Message-ID: CALL FOR WORKSHOP AND CO-LOCATED EVENT PROPOSALS ICFP 2024 29th ACM SIGPLAN International Conference on Functional Programming September 2 - 7, 2024 Milan, Italy https://icfp24.sigplan.org/ The 29th ACM SIGPLAN International Conference on Functional Programming will be held in Milan, Italy on September 2 - 7, 2024, with the option of virtual participation. ICFP provides a forum for researchers and developers to hear about the latest work on the design, implementations, principles, and uses of functional programming. Proposals are invited for workshops (and other co-located events, such as symposiums) to be affiliated with ICFP 2024 and sponsored by SIGPLAN. These events should be less formal and more focused than ICFP itself, include sessions that enable interaction among the attendees, and foster the exchange of new ideas. The preference is for one-day events, but other schedules can also be considered. The workshops are scheduled to occur on September 2nd (the day before ICFP) and September 6-7th (the two days after ICFP). A separate call for Call for Tutorial, Panel, and Discussion Proposals is going to be circulated later. ---------------------------------------------------------------------- Submission details Deadline for submission: January 11, 2024 Notification of acceptance: January 19, 2024 Prospective organizers of workshops or other co-located events are invited to submit a completed workshop proposal form in plain text format to the ICFP 2024 workshop co-chairs (Chandrakana Nandi and Yannick Forster) via email to chandra at certora.com yannick.forster at inria.fr by January 11, 2024. (For proposals of co-located events other than workshops, please fill in the workshop proposal form and just leave blank any sections that do not apply.) Please note that this is a firm deadline. Organizers will be notified whether their event proposal is accepted by January 19, 2024, and if successful, depending on the event, they will be asked to produce a final report after the event has taken place that is suitable for publication in SIGPLAN Notices. The proposal form is available at: http://www.icfpconference.org/icfp2024-files/icfp24-workshops-form.txt.docx PC Template: http://www.icfpconference.org/icfp2024-files/pc-template.xlsx Further information about SIGPLAN sponsorship is available at: http://www.sigplan.org/Resources/Proposals/Sponsored/ ---------------------------------------------------------------------- Selection committee The proposals will be evaluated by a committee comprising the following members of the ICFP 2024 organizing committee, together with the members of the SIGPLAN executive committee. Workshop Co-Chair: Chandrakana Nandi (Certora) Workshop Co-Chair: Yannick Forster (Inria) General Chair: Marco Gaboardi (Boston University) Program Chair: Brigitte Pientka (McGill University) ---------------------------------------------------------------------- Further information Any queries should be addressed to the workshop co-chairs (Chandrakana Nandi and Yannick Forster), via email to chandra at certora.com end yannick.forster at inria.fr -------------- next part -------------- An HTML attachment was scrubbed... URL: From markus.l2ll at gmail.com Wed Dec 13 18:27:57 2023 From: markus.l2ll at gmail.com (=?UTF-8?B?TWFya3VzIEzDpGxs?=) Date: Wed, 13 Dec 2023 20:27:57 +0200 Subject: [Haskell-cafe] Package takeover request for socks Message-ID: Hi I would like to take over maintainership of the socks package (as in the SOCKS network proxy protocol). Vincent announced archiving the package in September[1] (I'm also cc'ing him here). The github repository is here[2]. Unless there are objections, my plan is to simply maintain it under my own github account, because when I took over rapid, I created a new github organization for it. But until there are other people interested in contributing, then having an org for each library is not worth it IMO. [1] https://twitter.com/vincenthz/status/1704395906374889934 [2] https://github.com/vincenthz/hs-socks -- Markus Läll -------------- next part -------------- An HTML attachment was scrubbed... URL: From stefan.wehr at gmail.com Fri Dec 15 14:34:18 2023 From: stefan.wehr at gmail.com (Stefan Wehr) Date: Fri, 15 Dec 2023 15:34:18 +0100 Subject: [Haskell-cafe] Call for Participation: BOB 2024 (Berlin, March 15) Message-ID: ========================================================================= BOB 2024 Conference “What happens if we simply use what’s best?” March 15, 2024, Berlin https://bobkonf.de/2024/ Program: https://bobkonf.de/2024/program.html Registration: https://bobkonf.de/2024/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: https://bobkonf.de/2024/program.html Talk subjects includes functional programming, property-based testing, service API design, programming for spacecraft, accessibility, hypermedia, business processes, software analytics, event-based communication and zero-knowledge proofs. BOB will feature tutorials on F#, Haskell, Lean, SwiftUI, Copilot, the K Framework, functional domain modelling, and Liberating Structures. Andreas Rossberg will give the keynote talk. Registration is open - online tickets are all under 200€, and many discount options are available, as are grants for members of groups underrepresented in tech: https://bobkonf.de/2024/registration.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From jgbm at acm.org Wed Dec 20 02:57:27 2023 From: jgbm at acm.org (J. Garrett Morris) Date: Tue, 19 Dec 2023 20:57:27 -0600 Subject: [Haskell-cafe] RFC: Changes to the Haskell Symposium Message-ID: Dear Haskellers, In recent years, submissions to the Haskell Symposium have dropped precipitously: from 37 in 2017 to just 15 in 2023. This has made it increasingly challenging for the program committee to put together a program that is vibrant and intellectually rigorous. The Haskell Symposium steering committee has developed two proposals to reinvigorate the Symposium. The first is to invite a new category of presentations of work-in-progress results; the second is to submit accepted papers to the Journal of Functional Programming for publication rather than continuing the Symposium's proceedings. A full description of the proposed changes can be found on the Haskell Foundation's GitHub: https://github.com/haskellfoundation/tech-proposals/pull/62. We invite feedback from the community, particularly on how these changes would effect your participation (either as authors or attendees) in the future. Yours, /g J. Garrett Morris PC Co-chair, 2024 Haskell Symposium For the Haskell Symposium Steering Committee -------------- next part -------------- An HTML attachment was scrubbed... URL: From P.Achten at cs.ru.nl Fri Dec 22 09:09:28 2023 From: P.Achten at cs.ru.nl (Peter Achten) Date: Fri, 22 Dec 2023 10:09:28 +0100 Subject: [Haskell-cafe] [TFP (and TFPiE) 2024] Call For Participation (January 9-12, Seton Hall University, NJ, USA) Message-ID: <5e3fa53f9432279222e83752c0c1d236@cs.ru.nl> # TFP 2024 -- Call For Participation (trendsfp.github.io) ## Venue TFPiE and TFP will take place in-person at Seton Hall University, New Jersey in the United States. ## Dates TFPiE Workshop: Tuesday 9th January, 2024 TFP Symposium: Wednesday 10th - Friday 12th January, 2024 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. ## Keynote speakers We are happy to have the following keynotes in the programme: * Jeremy Gibbons, Oxford University * Benjamin Pierce, University of Pennsylvania * John Reppy, University of Chicago ## Programme The programme schedule can be found here: trendsfp.github.io/schedule.html ## Excursion and banquet After lunch on Thursday there is a private guided tour of the Thomas Edison National Historical Park and Museum. Thursday evening we have the TFP banquet at Forno's of Spain. During dinner the winners of the best paper awards of last year's TFP will be announced. -------------- next part -------------- An HTML attachment was scrubbed... URL: