From eacameron at gmail.com Tue Nov 1 23:13:42 2016 From: eacameron at gmail.com (Elliot Cameron) Date: Tue, 1 Nov 2016 19:13:42 -0400 Subject: Type Level "Application" Operator Message-ID: Folks, Has there been a discussion about adding a type-level operator "$" that just mimics "$" at the value level? type f $ x = f x infixr 0 $ Things like monad transformer stacks would look more "stack-like" with this: type App = ExceptT Err $ ReaderT Config $ LogT Text IO Elliot Cameron -------------- next part -------------- An HTML attachment was scrubbed... URL: From evincarofautumn at gmail.com Wed Nov 2 06:31:05 2016 From: evincarofautumn at gmail.com (Jon Purdy) Date: Tue, 1 Nov 2016 23:31:05 -0700 Subject: Type Level "Application" Operator In-Reply-To: References: Message-ID: +1 from me, if only as a nice-to-have—it would be good to flesh out some standard type operators in general. On Nov 1, 2016 4:14 PM, "Elliot Cameron" wrote: > Folks, > > Has there been a discussion about adding a type-level operator "$" that > just mimics "$" at the value level? > > type f $ x = f x > infixr 0 $ > > Things like monad transformer stacks would look more "stack-like" with > this: > > type App = ExceptT Err $ ReaderT Config $ LogT Text IO > > Elliot Cameron > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jeffbrown.the at gmail.com Wed Nov 2 07:31:55 2016 From: jeffbrown.the at gmail.com (Jeffrey Brown) Date: Wed, 2 Nov 2016 00:31:55 -0700 Subject: Type Level "Application" Operator In-Reply-To: References: Message-ID: +1! Readability improvements are wonderful. On Tue, Nov 1, 2016 at 11:31 PM, Jon Purdy wrote: > +1 from me, if only as a nice-to-have—it would be good to flesh out some > standard type operators in general. > > On Nov 1, 2016 4:14 PM, "Elliot Cameron" wrote: > >> Folks, >> >> Has there been a discussion about adding a type-level operator "$" that >> just mimics "$" at the value level? >> >> type f $ x = f x >> infixr 0 $ >> >> Things like monad transformer stacks would look more "stack-like" with >> this: >> >> type App = ExceptT Err $ ReaderT Config $ LogT Text IO >> >> Elliot Cameron >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> >> > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > -- Jeff Brown | Jeffrey Benjamin Brown Website | Facebook | LinkedIn (I often miss messages here) | Github -------------- next part -------------- An HTML attachment was scrubbed... URL: From ekmett at gmail.com Wed Nov 2 14:24:12 2016 From: ekmett at gmail.com (Edward Kmett) Date: Wed, 2 Nov 2016 10:24:12 -0400 Subject: Type Level "Application" Operator In-Reply-To: References: Message-ID: +1, but the operator you're looking for in App there would actually be a type level version of (.). type App a = ExceptT Err $ ReaderT Config $ LogT Text $ IO a type App = ExceptT Err . ReaderT Config . LogT Text . IO which would need type (.) f g x = f (g x) infixr 9 . to parse -Edward On Tue, Nov 1, 2016 at 7:13 PM, Elliot Cameron wrote: > Folks, > > Has there been a discussion about adding a type-level operator "$" that > just mimics "$" at the value level? > > type f $ x = f x > infixr 0 $ > > Things like monad transformer stacks would look more "stack-like" with > this: > > type App = ExceptT Err $ ReaderT Config $ LogT Text IO > > Elliot Cameron > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From oleg.grenrus at iki.fi Wed Nov 2 14:42:25 2016 From: oleg.grenrus at iki.fi (Oleg Grenrus) Date: Wed, 2 Nov 2016 16:42:25 +0200 Subject: Type Level "Application" Operator In-Reply-To: References: Message-ID: To make it clear: type level `.` won’t work as an type synonym, as it’s application isn’t saturated. {-# LANGUAGE TypeOperators #-} type (:.:) f g x = f (g x) infixr 9 :.: type App = Maybe :.: [] fails to compile with following errors (for a reason): • The type synonym ‘:.:’ should have 3 arguments, but has been given 2 • In the type synonym declaration for ‘App’ > On 02 Nov 2016, at 16:24, Edward Kmett wrote: > > +1, but the operator you're looking for in App there would actually be a type level version of (.). > > type App a = ExceptT Err $ ReaderT Config $ LogT Text $ IO a > > type App = ExceptT Err . ReaderT Config . LogT Text . IO > > which would need > > type (.) f g x = f (g x) > infixr 9 . > > to parse > > -Edward > > On Tue, Nov 1, 2016 at 7:13 PM, Elliot Cameron wrote: > Folks, > > Has there been a discussion about adding a type-level operator "$" that just mimics "$" at the value level? > > type f $ x = f x > infixr 0 $ > > Things like monad transformer stacks would look more "stack-like" with this: > > type App = ExceptT Err $ ReaderT Config $ LogT Text IO > > Elliot Cameron > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 842 bytes Desc: Message signed with OpenPGP using GPGMail URL: From eacameron at gmail.com Wed Nov 2 14:54:51 2016 From: eacameron at gmail.com (Elliot Cameron) Date: Wed, 2 Nov 2016 10:54:51 -0400 Subject: Type Level "Application" Operator In-Reply-To: References: Message-ID: Edward, I had the exact same thought but I couldn't get it to work. Oddly enough, I actually copied and pasted that example from my code which builds and runs perfectly well. It seems that monad transformers work differently when defined as a type (instead of newtype, which would require me to include the type parameter)? Somewhat related is the question of how to actually *export* this type alias from a module. > module Money (($)) where > > type f $ x = f x > infixr 0 $ doesn't work because it tries to export Prelude.$. The only way around it is to import Prelude hiding (($)). But this makes me wonder, is it actually *impossible* in Haskell to export from the same module a function with the same name at both the value and type level? Is it possible to export only one of the two? Elliot On Wed, Nov 2, 2016 at 10:42 AM, Oleg Grenrus wrote: > To make it clear: > > type level `.` won’t work as an type synonym, as it’s application isn’t > saturated. > > {-# LANGUAGE TypeOperators #-} > type (:.:) f g x = f (g x) > infixr 9 :.: > > type App = Maybe :.: [] > > fails to compile with following errors (for a reason): > > • The type synonym ‘:.:’ should have 3 arguments, but has been given 2 > • In the type synonym declaration for ‘App’ > > > On 02 Nov 2016, at 16:24, Edward Kmett wrote: > > > > +1, but the operator you're looking for in App there would actually be a > type level version of (.). > > > > type App a = ExceptT Err $ ReaderT Config $ LogT Text $ IO a > > > > type App = ExceptT Err . ReaderT Config . LogT Text . IO > > > > which would need > > > > type (.) f g x = f (g x) > > infixr 9 . > > > > to parse > > > > -Edward > > > > On Tue, Nov 1, 2016 at 7:13 PM, Elliot Cameron > wrote: > > Folks, > > > > Has there been a discussion about adding a type-level operator "$" that > just mimics "$" at the value level? > > > > type f $ x = f x > > infixr 0 $ > > > > Things like monad transformer stacks would look more "stack-like" with > this: > > > > type App = ExceptT Err $ ReaderT Config $ LogT Text IO > > > > Elliot Cameron > > > > _______________________________________________ > > Libraries mailing list > > Libraries at haskell.org > > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > > > > > _______________________________________________ > > Libraries mailing list > > Libraries at haskell.org > > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ryan.gl.scott at gmail.com Wed Nov 2 15:33:57 2016 From: ryan.gl.scott at gmail.com (Ryan Scott) Date: Wed, 2 Nov 2016 11:33:57 -0400 Subject: Type Level "Application" Operator Message-ID: > But this makes me wonder, is it actually *impossible* in Haskell to export from the same module a function with the same name at both the value and type level? Is it possible to export only one of the two? It's quite possible. You just have to use the "type" namespace in your export list to disambiguate the term-level and type-level ($)s: {-# LANGUAGE TypeOperators #-} module Money (($), type ($)) where type f $ x = f x infixr 0 $ Also, +1 on the original suggestion to add ($) to base. Ryan S. From ryan.gl.scott at gmail.com Wed Nov 2 15:40:08 2016 From: ryan.gl.scott at gmail.com (Ryan Scott) Date: Wed, 2 Nov 2016 11:40:08 -0400 Subject: Proposal: Add Data instance for Const Message-ID: GHC Trac #12438 [1] exists because there's no Data instance for Const in base. I found this quite surprising, since we have Data instances for just about every other type combinator out there (Identity, Sum, Product, Compose, etc.), but not for Const. The fix for #12438 would be quite simple: I propose we add deriving instance (Data a, Data b) => Data (Const a b) to Data.Data in base. Any objections? Ryan S. ----- [1] https://ghc.haskell.org/trac/ghc/ticket/12438 From emertens at gmail.com Wed Nov 2 15:41:47 2016 From: emertens at gmail.com (Eric Mertens) Date: Wed, 2 Nov 2016 08:41:47 -0700 Subject: Proposal: Add Data instance for Const In-Reply-To: References: Message-ID: <8E87D287-3CBE-4B2F-B990-9AE3EEDF014A@gmail.com> > On Nov 2, 2016, at 8:40 AM, Ryan Scott wrote: > > GHC Trac #12438 [1] exists because there's no Data instance for Const > in base. I found this quite surprising, since we have Data instances > for just about every other type combinator out there (Identity, Sum, > Product, Compose, etc.), but not for Const. The fix for #12438 would > be quite simple: I propose we add > > deriving instance (Data a, Data b) => Data (Const a b) > > to Data.Data in base. Any objections? Seems like an oversight worth correcting to me. -- Eric From ekmett at gmail.com Wed Nov 2 16:05:07 2016 From: ekmett at gmail.com (Edward Kmett) Date: Wed, 2 Nov 2016 12:05:07 -0400 Subject: Proposal: Add Data instance for Const In-Reply-To: References: Message-ID: Definitely an oversight. On Wed, Nov 2, 2016 at 11:40 AM, Ryan Scott wrote: > GHC Trac #12438 [1] exists because there's no Data instance for Const > in base. I found this quite surprising, since we have Data instances > for just about every other type combinator out there (Identity, Sum, > Product, Compose, etc.), but not for Const. The fix for #12438 would > be quite simple: I propose we add > > deriving instance (Data a, Data b) => Data (Const a b) > > to Data.Data in base. Any objections? > > Ryan S. > ----- > [1] https://ghc.haskell.org/trac/ghc/ticket/12438 > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ekmett at gmail.com Wed Nov 2 16:35:12 2016 From: ekmett at gmail.com (Edward Kmett) Date: Wed, 2 Nov 2016 12:35:12 -0400 Subject: Type Level "Application" Operator In-Reply-To: References: Message-ID: <773CBCA2-44CF-4074-B284-9ADFE9BB5B23@gmail.com> To make . work, we'd need both the ability to parse . at the type level without the compiler flipping out and assuming it is part of a rank n signature (which was the first issue I was trying to mention) and a form of "Really LiberalTypeSynonyms" like we use in ermine to allow the partial application so long as App is only used applied to an argument. In theory non recursive partial application of type synonyms within a type synonym is perfectly admissible in Haskell type checking, it just complicates the expansion and we don't do it today. Both are solvable, but are nowhere near the low hanging fruit that adding $ would be. -Edward > On Nov 2, 2016, at 10:42 AM, Oleg Grenrus wrote: > > To make it clear: > > type level `.` won’t work as an type synonym, as it’s application isn’t saturated. > > {-# LANGUAGE TypeOperators #-} > type (:.:) f g x = f (g x) > infixr 9 :.: > > type App = Maybe :.: [] > > fails to compile with following errors (for a reason): > > • The type synonym ‘:.:’ should have 3 arguments, but has been given 2 > • In the type synonym declaration for ‘App’ > >> On 02 Nov 2016, at 16:24, Edward Kmett wrote: >> >> +1, but the operator you're looking for in App there would actually be a type level version of (.). >> >> type App a = ExceptT Err $ ReaderT Config $ LogT Text $ IO a >> >> type App = ExceptT Err . ReaderT Config . LogT Text . IO >> >> which would need >> >> type (.) f g x = f (g x) >> infixr 9 . >> >> to parse >> >> -Edward >> >> On Tue, Nov 1, 2016 at 7:13 PM, Elliot Cameron wrote: >> Folks, >> >> Has there been a discussion about adding a type-level operator "$" that just mimics "$" at the value level? >> >> type f $ x = f x >> infixr 0 $ >> >> Things like monad transformer stacks would look more "stack-like" with this: >> >> type App = ExceptT Err $ ReaderT Config $ LogT Text IO >> >> Elliot Cameron >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From vlad.z.4096 at gmail.com Wed Nov 2 19:11:43 2016 From: vlad.z.4096 at gmail.com (Index Int) Date: Wed, 2 Nov 2016 22:11:43 +0300 Subject: Type Level "Application" Operator In-Reply-To: References: Message-ID: Edward, I don't quite follow why you think that (.) is needed here. Monad transformers take two parameters, so your example is not type-correct, whereas the original one is. On Wed, Nov 2, 2016 at 5:24 PM, Edward Kmett wrote: > +1, but the operator you're looking for in App there would actually be a > type level version of (.). > > type App a = ExceptT Err $ ReaderT Config $ LogT Text $ IO a > > type App = ExceptT Err . ReaderT Config . LogT Text . IO > > which would need > > type (.) f g x = f (g x) > infixr 9 . > > to parse > > -Edward > > On Tue, Nov 1, 2016 at 7:13 PM, Elliot Cameron wrote: >> >> Folks, >> >> Has there been a discussion about adding a type-level operator "$" that >> just mimics "$" at the value level? >> >> type f $ x = f x >> infixr 0 $ >> >> Things like monad transformer stacks would look more "stack-like" with >> this: >> >> type App = ExceptT Err $ ReaderT Config $ LogT Text IO >> >> Elliot Cameron >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> > > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > From vlad.z.4096 at gmail.com Wed Nov 2 19:16:51 2016 From: vlad.z.4096 at gmail.com (Index Int) Date: Wed, 2 Nov 2016 22:16:51 +0300 Subject: Proposal: Add Data instance for Const In-Reply-To: References: Message-ID: The proposed instance is overconstrained. You only need Typeable for the second argument of Const (because it is phantom). On Wed, Nov 2, 2016 at 7:05 PM, Edward Kmett wrote: > Definitely an oversight. > > On Wed, Nov 2, 2016 at 11:40 AM, Ryan Scott wrote: >> >> GHC Trac #12438 [1] exists because there's no Data instance for Const >> in base. I found this quite surprising, since we have Data instances >> for just about every other type combinator out there (Identity, Sum, >> Product, Compose, etc.), but not for Const. The fix for #12438 would >> be quite simple: I propose we add >> >> deriving instance (Data a, Data b) => Data (Const a b) >> >> to Data.Data in base. Any objections? >> >> Ryan S. >> ----- >> [1] https://ghc.haskell.org/trac/ghc/ticket/12438 >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > From ryan.gl.scott at gmail.com Wed Nov 2 19:27:39 2016 From: ryan.gl.scott at gmail.com (Ryan Scott) Date: Wed, 2 Nov 2016 15:27:39 -0400 Subject: Proposal: Add Data instance for Const In-Reply-To: References: Message-ID: > The proposed instance is overconstrained. You only need Typeable for the second argument of Const (because it is phantom). It's a phantom type, but the Data constraint is necessary because the way deriving Data works. If You can read this [1] for an explanation behind this design decision. Essentially, if GHC sees that a datatype has two type parameters of kind *, then it generates a definition for the dataCast2 method, which allows for a higher-order version of the cast function. But implementing dataCast2 requires that both type parameters be Data instances. A separate question would be whether implementing dataCast2 could be done without these Data constraints (and thus allowing the second type parameter to only be an instance of Typeable, rather than Data). But that is outside my area of expertise; I'd need someone more knowledgeable in the arts of Data.Data than I. For now, I am proposing what GHC currently considers to be a canonical Data instance for Const. We can revisit the exact instance context details later if need be. Ryan S. ----- [1] https://ghc.haskell.org/trac/ghc/ticket/4028 On Wed, Nov 2, 2016 at 3:16 PM, Index Int wrote: > The proposed instance is overconstrained. You only need Typeable for > the second argument of Const (because it is phantom). > > On Wed, Nov 2, 2016 at 7:05 PM, Edward Kmett wrote: > > Definitely an oversight. > > > > On Wed, Nov 2, 2016 at 11:40 AM, Ryan Scott > wrote: > >> > >> GHC Trac #12438 [1] exists because there's no Data instance for Const > >> in base. I found this quite surprising, since we have Data instances > >> for just about every other type combinator out there (Identity, Sum, > >> Product, Compose, etc.), but not for Const. The fix for #12438 would > >> be quite simple: I propose we add > >> > >> deriving instance (Data a, Data b) => Data (Const a b) > >> > >> to Data.Data in base. Any objections? > >> > >> Ryan S. > >> ----- > >> [1] https://ghc.haskell.org/trac/ghc/ticket/12438 > >> _______________________________________________ > >> Libraries mailing list > >> Libraries at haskell.org > >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > > > > > > > _______________________________________________ > > Libraries mailing list > > Libraries at haskell.org > > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From vlad.z.4096 at gmail.com Wed Nov 2 20:17:49 2016 From: vlad.z.4096 at gmail.com (Index Int) Date: Wed, 2 Nov 2016 23:17:49 +0300 Subject: Proposal: Add Data instance for Const In-Reply-To: References: Message-ID: You propose to add the line deriving instance (Data a, Data b) => Data (Const a b) to Data.Data in base. I entered it into GHCi with -ddump-deriv and this is what I got: ghci> deriving instance (Data a, Data b) => Data (Const a b) ==================== Derived instances ==================== Derived instances: instance (Data.Data.Data a_a53b, Data.Data.Data b_a53c) => Data.Data.Data (Data.Functor.Const.Const a_a53b b_a53c) where Data.Data.gfoldl k_a53f z_a53g (Data.Functor.Const.Const a1_a53h) = (z_a53g Data.Functor.Const.Const `k_a53f` a1_a53h) Data.Data.gunfold k_a53i z_a53j _ = k_a53i (z_a53j Data.Functor.Const.Const) Data.Data.toConstr (Data.Functor.Const.Const _) = Ghci4.$cBHDVlUg6FI9L4iOviG5mer Data.Data.dataTypeOf _ = Ghci4.$tBHDVlUg6FI9L4iOviG5mer Ghci4.$tBHDVlUg6FI9L4iOviG5mer :: Data.Data.DataType Ghci4.$cBHDVlUg6FI9L4iOviG5mer :: Data.Data.Constr Ghci4.$tBHDVlUg6FI9L4iOviG5mer = Data.Data.mkDataType "Const" [Ghci4.$cBHDVlUg6FI9L4iOviG5mer] Ghci4.$cBHDVlUg6FI9L4iOviG5mer = Data.Data.mkConstr Ghci4.$tBHDVlUg6FI9L4iOviG5mer "Const" ["getConst"] Data.Data.Prefix So GHC does not generate a definition for dataCast2 (and it default to `const Nothing`, I suppose). I tried the same with the constraint relaxed to Typeable and it worked. Am I missing something? On Wed, Nov 2, 2016 at 10:27 PM, Ryan Scott wrote: >> The proposed instance is overconstrained. You only need Typeable for the >> second argument of Const (because it is phantom). > > It's a phantom type, but the Data constraint is necessary because the way > deriving Data works. If You can read this [1] for an explanation behind > this design decision. Essentially, if GHC sees that a datatype has two type > parameters of kind *, then it generates a definition for the dataCast2 > method, which allows for a higher-order version of the cast function. But > implementing dataCast2 requires that both type parameters be Data instances. > > A separate question would be whether implementing dataCast2 could be done > without these Data constraints (and thus allowing the second type parameter > to only be an instance of Typeable, rather than Data). But that is outside > my area of expertise; I'd need someone more knowledgeable in the arts of > Data.Data than I. > > For now, I am proposing what GHC currently considers to be a canonical Data > instance for Const. We can revisit the exact instance context details later > if need be. > > Ryan S. > ----- > [1] https://ghc.haskell.org/trac/ghc/ticket/4028 > > On Wed, Nov 2, 2016 at 3:16 PM, Index Int wrote: >> >> The proposed instance is overconstrained. You only need Typeable for >> the second argument of Const (because it is phantom). >> >> On Wed, Nov 2, 2016 at 7:05 PM, Edward Kmett wrote: >> > Definitely an oversight. >> > >> > On Wed, Nov 2, 2016 at 11:40 AM, Ryan Scott >> > wrote: >> >> >> >> GHC Trac #12438 [1] exists because there's no Data instance for Const >> >> in base. I found this quite surprising, since we have Data instances >> >> for just about every other type combinator out there (Identity, Sum, >> >> Product, Compose, etc.), but not for Const. The fix for #12438 would >> >> be quite simple: I propose we add >> >> >> >> deriving instance (Data a, Data b) => Data (Const a b) >> >> >> >> to Data.Data in base. Any objections? >> >> >> >> Ryan S. >> >> ----- >> >> [1] https://ghc.haskell.org/trac/ghc/ticket/12438 >> >> _______________________________________________ >> >> Libraries mailing list >> >> Libraries at haskell.org >> >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> > >> > >> > >> > _______________________________________________ >> > Libraries mailing list >> > Libraries at haskell.org >> > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> > > > From ryan.gl.scott at gmail.com Wed Nov 2 20:33:09 2016 From: ryan.gl.scott at gmail.com (Ryan Scott) Date: Wed, 2 Nov 2016 16:33:09 -0400 Subject: Proposal: Add Data instance for Const In-Reply-To: References: Message-ID: Ah, right. I forgot about this additional wrinkle - GHC only checks the kinds of each type variable at the definition site, not at the site of the Data instance. And Const is poly-kinded, so its second type variable is of kind k, not *, so that's why GHC forgoes defining dataCast2 here. My bad. So in this case, I suppose it doesn't hurt to relax the second constraint to Typeable. There's the separate issue of whether this is a "correct" Data instance, but GHC won't allow us to derive dataCast2 for the Data (Const a b) instance in the first place, so it's a bit of a moot point. Ryan S. On Wed, Nov 2, 2016 at 4:17 PM, Index Int wrote: > You propose to add the line > > deriving instance (Data a, Data b) => Data (Const a b) > > to Data.Data in base. I entered it into GHCi with -ddump-deriv and > this is what I got: > > ghci> deriving instance (Data a, Data b) => Data (Const a b) > > ==================== Derived instances ==================== > Derived instances: > instance (Data.Data.Data a_a53b, Data.Data.Data b_a53c) => > Data.Data.Data (Data.Functor.Const.Const a_a53b b_a53c) where > Data.Data.gfoldl k_a53f z_a53g (Data.Functor.Const.Const a1_a53h) > = (z_a53g Data.Functor.Const.Const `k_a53f` a1_a53h) > Data.Data.gunfold k_a53i z_a53j _ > = k_a53i (z_a53j Data.Functor.Const.Const) > Data.Data.toConstr (Data.Functor.Const.Const _) > = Ghci4.$cBHDVlUg6FI9L4iOviG5mer > Data.Data.dataTypeOf _ = Ghci4.$tBHDVlUg6FI9L4iOviG5mer > > Ghci4.$tBHDVlUg6FI9L4iOviG5mer :: Data.Data.DataType > Ghci4.$cBHDVlUg6FI9L4iOviG5mer :: Data.Data.Constr > Ghci4.$tBHDVlUg6FI9L4iOviG5mer > = Data.Data.mkDataType "Const" [Ghci4.$cBHDVlUg6FI9L4iOviG5mer] > Ghci4.$cBHDVlUg6FI9L4iOviG5mer > = Data.Data.mkConstr > Ghci4.$tBHDVlUg6FI9L4iOviG5mer > "Const" > ["getConst"] > Data.Data.Prefix > > So GHC does not generate a definition for dataCast2 (and it default to > `const Nothing`, I suppose). I tried the same with the constraint > relaxed to Typeable and it worked. Am I missing something? > > On Wed, Nov 2, 2016 at 10:27 PM, Ryan Scott > wrote: > >> The proposed instance is overconstrained. You only need Typeable for the > >> second argument of Const (because it is phantom). > > > > It's a phantom type, but the Data constraint is necessary because the way > > deriving Data works. If You can read this [1] for an explanation behind > > this design decision. Essentially, if GHC sees that a datatype has two > type > > parameters of kind *, then it generates a definition for the dataCast2 > > method, which allows for a higher-order version of the cast function. But > > implementing dataCast2 requires that both type parameters be Data > instances. > > > > A separate question would be whether implementing dataCast2 could be done > > without these Data constraints (and thus allowing the second type > parameter > > to only be an instance of Typeable, rather than Data). But that is > outside > > my area of expertise; I'd need someone more knowledgeable in the arts of > > Data.Data than I. > > > > For now, I am proposing what GHC currently considers to be a canonical > Data > > instance for Const. We can revisit the exact instance context details > later > > if need be. > > > > Ryan S. > > ----- > > [1] https://ghc.haskell.org/trac/ghc/ticket/4028 > > > > On Wed, Nov 2, 2016 at 3:16 PM, Index Int wrote: > >> > >> The proposed instance is overconstrained. You only need Typeable for > >> the second argument of Const (because it is phantom). > >> > >> On Wed, Nov 2, 2016 at 7:05 PM, Edward Kmett wrote: > >> > Definitely an oversight. > >> > > >> > On Wed, Nov 2, 2016 at 11:40 AM, Ryan Scott > >> > wrote: > >> >> > >> >> GHC Trac #12438 [1] exists because there's no Data instance for Const > >> >> in base. I found this quite surprising, since we have Data instances > >> >> for just about every other type combinator out there (Identity, Sum, > >> >> Product, Compose, etc.), but not for Const. The fix for #12438 would > >> >> be quite simple: I propose we add > >> >> > >> >> deriving instance (Data a, Data b) => Data (Const a b) > >> >> > >> >> to Data.Data in base. Any objections? > >> >> > >> >> Ryan S. > >> >> ----- > >> >> [1] https://ghc.haskell.org/trac/ghc/ticket/12438 > >> >> _______________________________________________ > >> >> Libraries mailing list > >> >> Libraries at haskell.org > >> >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > >> > > >> > > >> > > >> > _______________________________________________ > >> > Libraries mailing list > >> > Libraries at haskell.org > >> > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > >> > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ekmett at gmail.com Wed Nov 2 22:27:59 2016 From: ekmett at gmail.com (Edward Kmett) Date: Wed, 2 Nov 2016 18:27:59 -0400 Subject: Type Level "Application" Operator In-Reply-To: References: Message-ID: On Wed, Nov 2, 2016 at 3:11 PM, Index Int wrote: > Edward, I don't quite follow why you think that (.) is needed here. > Monad transformers take two parameters, so your example is not > type-correct, whereas the original one is. > Indeed, I appear to have hyper-corrected that example. -Edward On Wed, Nov 2, 2016 at 5:24 PM, Edward Kmett wrote: > > +1, but the operator you're looking for in App there would actually be a > > type level version of (.). > > > > type App a = ExceptT Err $ ReaderT Config $ LogT Text $ IO a > > > > type App = ExceptT Err . ReaderT Config . LogT Text . IO > > > > which would need > > > > type (.) f g x = f (g x) > > infixr 9 . > > > > to parse > > > > -Edward > > > > On Tue, Nov 1, 2016 at 7:13 PM, Elliot Cameron > wrote: > >> > >> Folks, > >> > >> Has there been a discussion about adding a type-level operator "$" that > >> just mimics "$" at the value level? > >> > >> type f $ x = f x > >> infixr 0 $ > >> > >> Things like monad transformer stacks would look more "stack-like" with > >> this: > >> > >> type App = ExceptT Err $ ReaderT Config $ LogT Text IO > >> > >> Elliot Cameron > >> > >> _______________________________________________ > >> Libraries mailing list > >> Libraries at haskell.org > >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > >> > > > > > > _______________________________________________ > > Libraries mailing list > > Libraries at haskell.org > > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From novadenizen at gmail.com Wed Nov 2 23:36:04 2016 From: novadenizen at gmail.com (Ken Bateman) Date: Wed, 2 Nov 2016 19:36:04 -0400 Subject: Type Level "Application" Operator In-Reply-To: References: Message-ID: Wouldn't there also be a problem with type unification? When unifying ((f . g) a) and (h b) do you set ((f . g) ~ h) or ((g a) ~ b)? On Nov 2, 2016 6:28 PM, "Edward Kmett" wrote: > On Wed, Nov 2, 2016 at 3:11 PM, Index Int wrote: > >> Edward, I don't quite follow why you think that (.) is needed here. >> Monad transformers take two parameters, so your example is not >> type-correct, whereas the original one is. >> > > Indeed, I appear to have hyper-corrected that example. > > -Edward > > On Wed, Nov 2, 2016 at 5:24 PM, Edward Kmett wrote: >> > +1, but the operator you're looking for in App there would actually be a >> > type level version of (.). >> > >> > type App a = ExceptT Err $ ReaderT Config $ LogT Text $ IO a >> > >> > type App = ExceptT Err . ReaderT Config . LogT Text . IO >> > >> > which would need >> > >> > type (.) f g x = f (g x) >> > infixr 9 . >> > >> > to parse >> > >> > -Edward >> > >> > On Tue, Nov 1, 2016 at 7:13 PM, Elliot Cameron >> wrote: >> >> >> >> Folks, >> >> >> >> Has there been a discussion about adding a type-level operator "$" that >> >> just mimics "$" at the value level? >> >> >> >> type f $ x = f x >> >> infixr 0 $ >> >> >> >> Things like monad transformer stacks would look more "stack-like" with >> >> this: >> >> >> >> type App = ExceptT Err $ ReaderT Config $ LogT Text IO >> >> >> >> Elliot Cameron >> >> >> >> _______________________________________________ >> >> Libraries mailing list >> >> Libraries at haskell.org >> >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> >> >> > >> > >> > _______________________________________________ >> > Libraries mailing list >> > Libraries at haskell.org >> > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> > >> > > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Thu Nov 3 00:05:32 2016 From: david.feuer at gmail.com (David Feuer) Date: Wed, 2 Nov 2016 20:05:32 -0400 Subject: Discussion: add pattern synonyms and a non-dependent eliminator to Numeric.Natural In-Reply-To: References: Message-ID: Pattern synonyms: pattern Successor :: Natural -> Natural pattern Successor n <- (precMaybe -> Just n) where Successor n = n + 1 precMaybe :: Natural -> Maybe Natural precMaybe 0 = Nothing precMaybe n = Just (n - 1) pattern Zero :: Natural pattern Zero = 0 Eliminator: toChurch :: Natural -> (a -> a) -> a -> a toChurch 0 _ b = b toChurch n f b = f (toChurch (n-1) f b) There are several other possible argument orders, the most natural of which is probably natural :: a -> (a -> a) -> Natural I don't have particularly strong feelings about whether we should pick one or offer both. There are two strictly accumulating versions, corresponding to different versions of foldl'. But toChurch/natural is sufficient to define them: toChurch', toChurch'' :: Natural -> (a -> a) -> a -> a toChurch' n f = toChurch n (\r acc -> r $! f acc) id toChurch'' n f = toChurch n (\r !acc -> r $ f acc) id So we shouldn't necessarily feel obligated to include those. I doubt the time is ripe for a dependent eliminator. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ekmett at gmail.com Thu Nov 3 01:01:37 2016 From: ekmett at gmail.com (Edward Kmett) Date: Wed, 2 Nov 2016 21:01:37 -0400 Subject: Type Level "Application" Operator In-Reply-To: References: Message-ID: Even with "ReallyLiberalTypeSynonyms" you can't have (f . g) ~ h as that would involve a partial application in a non type synonym, so there is no issue with unification. (.) only means something with all 3 arguments applied so that it can be expanded, but you can still allow it to be formally passed around inside other type synonyms so long as the final type synonym has all of its arguments expanded. type (.) f g x = f (g x) type Foo = (.) Bar Foo doesn't fully instantiate (.) but you can keep eta expanding it until it does. type Foo g x = (.) Bar g x = Bar (g x) is a perfectly legitimate definition. You can do this expansion automatically pretty easily. Given such a type synonym you can answer how many arguments it must have before it is a real type. At a use site Foo is not a type until it has been applied to two more arguments, just like the eta expanded form above. Foo ~ Baz doesn't type check for the same reason given type Id a = a you can't talk about Id ~ Bar. Id isn't a type. It needs an argument before it makes sense. This is what I mean by "ReallyLiberalTypeSynonyms". We actually wound up with these by accident in the Ermine compiler we use at work, and they turned out to be quite useful and harmless in practice. We don't have this power today, but we do have LiberalTypeSynonyms, which gets us close. -Edward On Wed, Nov 2, 2016 at 7:36 PM, Ken Bateman wrote: > Wouldn't there also be a problem with type unification? When unifying ((f > . g) a) and (h b) do you set ((f . g) ~ h) or ((g a) ~ b)? > > On Nov 2, 2016 6:28 PM, "Edward Kmett" wrote: > >> On Wed, Nov 2, 2016 at 3:11 PM, Index Int wrote: >> >>> Edward, I don't quite follow why you think that (.) is needed here. >>> Monad transformers take two parameters, so your example is not >>> type-correct, whereas the original one is. >>> >> >> Indeed, I appear to have hyper-corrected that example. >> >> -Edward >> >> On Wed, Nov 2, 2016 at 5:24 PM, Edward Kmett wrote: >>> > +1, but the operator you're looking for in App there would actually be >>> a >>> > type level version of (.). >>> > >>> > type App a = ExceptT Err $ ReaderT Config $ LogT Text $ IO a >>> > >>> > type App = ExceptT Err . ReaderT Config . LogT Text . IO >>> > >>> > which would need >>> > >>> > type (.) f g x = f (g x) >>> > infixr 9 . >>> > >>> > to parse >>> > >>> > -Edward >>> > >>> > On Tue, Nov 1, 2016 at 7:13 PM, Elliot Cameron >>> wrote: >>> >> >>> >> Folks, >>> >> >>> >> Has there been a discussion about adding a type-level operator "$" >>> that >>> >> just mimics "$" at the value level? >>> >> >>> >> type f $ x = f x >>> >> infixr 0 $ >>> >> >>> >> Things like monad transformer stacks would look more "stack-like" with >>> >> this: >>> >> >>> >> type App = ExceptT Err $ ReaderT Config $ LogT Text IO >>> >> >>> >> Elliot Cameron >>> >> >>> >> _______________________________________________ >>> >> Libraries mailing list >>> >> Libraries at haskell.org >>> >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >>> >> >>> > >>> > >>> > _______________________________________________ >>> > Libraries mailing list >>> > Libraries at haskell.org >>> > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >>> > >>> >> >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From tom-lists-haskell-cafe-2013 at jaguarpaw.co.uk Sun Nov 6 17:37:48 2016 From: tom-lists-haskell-cafe-2013 at jaguarpaw.co.uk (Tom Ellis) Date: Sun, 6 Nov 2016 17:37:48 +0000 Subject: Proposal: relax type of asProxyTypeOf Message-ID: <20161106173748.GJ6044@weber> Did anything ever come of this proposal to relax the type of asProxyType of? https://mail.haskell.org/pipermail/libraries/2014-December/024462.html i.e. change asProxyTypeOf :: a -> Proxy a -> a to asProxyTypeOf :: a -> proxy a -> a I posted this issue on the Trac https://ghc.haskell.org/trac/ghc/ticket/12805 but it was suggested I ask on the libraries list. Tom From david.feuer at gmail.com Sun Nov 6 19:31:07 2016 From: david.feuer at gmail.com (David Feuer) Date: Sun, 6 Nov 2016 14:31:07 -0500 Subject: Proposal: relax type of asProxyTypeOf In-Reply-To: <20161106173748.GJ6044@weber> References: <20161106173748.GJ6044@weber> Message-ID: I think flexibility about the proxy type has become the norm, and we should probably follow that guideline. However, it could theoretically break code. asProxyTypeOf x (pure "I'm a string") is currently accepted but would be rejected with the proposed change (since the proxy type isn't fixed, GHC doesn't know that it's Applicative). On Nov 6, 2016 12:37 PM, "Tom Ellis" < tom-lists-haskell-cafe-2013 at jaguarpaw.co.uk> wrote: > Did anything ever come of this proposal to relax the type of asProxyType > of? > > https://mail.haskell.org/pipermail/libraries/2014-December/024462.html > > i.e. change > > asProxyTypeOf :: a -> Proxy a -> a > > to > > asProxyTypeOf :: a -> proxy a -> a > > I posted this issue on the Trac > > https://ghc.haskell.org/trac/ghc/ticket/12805 > > but it was suggested I ask on the libraries list. > > Tom > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ekmett at gmail.com Mon Nov 7 01:08:01 2016 From: ekmett at gmail.com (Edward Kmett) Date: Sun, 6 Nov 2016 20:08:01 -0500 Subject: Proposal: relax type of asProxyTypeOf In-Reply-To: References: <20161106173748.GJ6044@weber> Message-ID: The code in `tagged` has been generalized for a couple of years now, but Data.Proxy either forked off of it before we made that generalization or simply didn't get the more generalized type when it was moved into base. I'm strongly +1 on this generalization for consistency with the tagged package and with the other combinators already in base. -Edward On Sun, Nov 6, 2016 at 2:31 PM, David Feuer wrote: > I think flexibility about the proxy type has become the norm, and we > should probably follow that guideline. However, it could theoretically > break code. > > asProxyTypeOf x (pure "I'm a string") > > is currently accepted but would be rejected with the proposed change > (since the proxy type isn't fixed, GHC doesn't know that it's Applicative). > > On Nov 6, 2016 12:37 PM, "Tom Ellis" jaguarpaw.co.uk> wrote: > >> Did anything ever come of this proposal to relax the type of asProxyType >> of? >> >> https://mail.haskell.org/pipermail/libraries/2014-December/ >> 024462.html >> >> i.e. change >> >> asProxyTypeOf :: a -> Proxy a -> a >> >> to >> >> asProxyTypeOf :: a -> proxy a -> a >> >> I posted this issue on the Trac >> >> https://ghc.haskell.org/trac/ghc/ticket/12805 >> >> but it was suggested I ask on the libraries list. >> >> Tom >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ryan.gl.scott at gmail.com Mon Nov 7 13:49:37 2016 From: ryan.gl.scott at gmail.com (Ryan Scott) Date: Mon, 7 Nov 2016 08:49:37 -0500 Subject: Proposal: relax type of asProxyTypeOf Message-ID: Oh, I didn't realize that the type had already been generalized in tagged! [1] I'm certainly +1 on this proposal. Ryan S. ----- [1] https://github.com/ekmett/tagged/blob/93cd87830733ed641409a2a14776973e8be600cc/old/Data/Proxy.hs#L264 -------------- next part -------------- An HTML attachment was scrubbed... URL: From fumiexcel at gmail.com Wed Nov 9 08:54:01 2016 From: fumiexcel at gmail.com (Fumiaki Kinoshita) Date: Wed, 9 Nov 2016 17:54:01 +0900 Subject: Proposal: relax type of asProxyTypeOf In-Reply-To: <20161106173748.GJ6044@weber> References: <20161106173748.GJ6044@weber> Message-ID: Strong +1 from me -------------- next part -------------- An HTML attachment was scrubbed... URL: From baldurpet at gmail.com Mon Nov 14 18:11:59 2016 From: baldurpet at gmail.com (=?UTF-8?Q?Baldur_Bl=C3=B6ndal?=) Date: Mon, 14 Nov 2016 18:11:59 +0000 Subject: =?UTF-8?B?UHJvcG9zYWw6IEFkZCDigJh0eXBlIGYgfj4gZyA9IGZvcmFsbCBhLiBmIGEgLT4gZyBh?= =?UTF-8?B?4oCZ?= Message-ID: What the subject says, add type f ~> g = forall a. f a -> g a to ‘base’. Further motivation (and arguments against) in GHC Trac ticket 12772 [1]. [1] https://ghc.haskell.org/trac/ghc/ticket/12772 -------------- next part -------------- An HTML attachment was scrubbed... URL: From emertens at gmail.com Mon Nov 14 18:36:31 2016 From: emertens at gmail.com (Eric Mertens) Date: Mon, 14 Nov 2016 18:36:31 +0000 Subject: =?UTF-8?B?UmU6IFByb3Bvc2FsOiBBZGQg4oCYdHlwZSBmIH4+IGcgPSBmb3JhbGwgYS4gZiBhIC0+IA==?= =?UTF-8?B?ZyBh4oCZ?= In-Reply-To: References: Message-ID: I'd prefer that we didn't prescribe a meaning to this generally useful type operator. This type synonym is very easy to define in any module where it's appropriate. On Mon, Nov 14, 2016 at 10:12 AM Baldur Blöndal wrote: > What the subject says, add > > type f ~> g = forall a. f a -> g a > > to ‘base’. Further motivation (and arguments against) in GHC Trac ticket > 12772 [1]. > > [1] https://ghc.haskell.org/trac/ghc/ticket/12772 > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Mon Nov 14 20:21:54 2016 From: david.feuer at gmail.com (David Feuer) Date: Mon, 14 Nov 2016 15:21:54 -0500 Subject: Proposal: Add portable eliminator for Data.Type.Equality Message-ID: Most of Data.Type.Equality can be supported by any Haskell implementation with Rank2Types and TypeOperators, using, for example, the well-known definition newtype a :~: b = Equality { subst :: forall f . f a -> f b } (The parts that can't be supported so are the gcastWith function, the ~~ constraint, and the == type family.) What's most prominently missing is the ability to *use* equality for anything beyond castWith without leaning on GHC's equality constraints. I propose that we add the eliminator subst as a function: subst :: a :~: b -> f a -> f b subst Refl x = x Note that we already have an introduction rule Control.Category.id :: a :~: a David Feuer From david.feuer at gmail.com Mon Nov 14 20:28:00 2016 From: david.feuer at gmail.com (David Feuer) Date: Mon, 14 Nov 2016 15:28:00 -0500 Subject: Proposal: Add portable eliminator for Data.Type.Equality In-Reply-To: References: Message-ID: Further support for my proposal: we already have the analogous partial version Data.Typeable.gcast :: forall a b c. (Typeable a, Typeable b) => c a -> Maybe (c b) On Mon, Nov 14, 2016 at 3:21 PM, David Feuer wrote: > Most of Data.Type.Equality can be supported by any Haskell > implementation with Rank2Types and TypeOperators, using, for example, > the well-known definition > > newtype a :~: b = Equality { subst :: forall f . f a -> f b } > > (The parts that can't be supported so are the gcastWith function, the > ~~ constraint, and the == type family.) > > What's most prominently missing is the ability to *use* equality for > anything beyond castWith without leaning on GHC's equality > constraints. > > I propose that we add the eliminator subst as a function: > > subst :: a :~: b -> f a -> f b > subst Refl x = x > > Note that we already have an introduction rule > > Control.Category.id :: a :~: a > > David Feuer From johnw at newartisans.com Mon Nov 14 21:48:01 2016 From: johnw at newartisans.com (John Wiegley) Date: Mon, 14 Nov 2016 13:48:01 -0800 Subject: Proposal: Add =?utf-8?Q?=E2=80=98type?= f ~> g = forall a. f a -> g =?utf-8?Q?a=E2=80=99?= In-Reply-To: (Eric Mertens's message of "Mon, 14 Nov 2016 18:36:31 +0000") References: Message-ID: >>>>> "EM" == Eric Mertens writes: EM> I'd prefer that we didn't prescribe a meaning to this generally useful EM> type operator. This type synonym is very easy to define in any module EM> where it's appropriate. I agree. Taking "~>" for natural transformations seems too specific. -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 From winterkoninkje at gmail.com Tue Nov 15 05:24:42 2016 From: winterkoninkje at gmail.com (wren romano) Date: Mon, 14 Nov 2016 21:24:42 -0800 Subject: Proposal: Add portable eliminator for Data.Type.Equality In-Reply-To: References: Message-ID: On Mon, Nov 14, 2016 at 12:21 PM, David Feuer wrote: > I propose that we add the eliminator subst as a function: > > subst :: a :~: b -> f a -> f b > subst Refl x = x I'm all for adding this function, but do note that the type is suboptimal since GHC lacks general functions (and higher-order pattern matching) at the type level. Which means we'll actually end up wanting a family of different "subst" functions to cover all the (relevant) cases the definition above would cover in a language like Agda, Coq, etc. E.g., Prelude> let x :: Either Bool Int; x = Right 42 Prelude> :t (`subst` x) (`subst` x) :: Int :~: b -> Either Bool b When I might've really wanted/meant (Bool :~: b -> Either b Int) -- Live well, ~wren From winterkoninkje at gmail.com Tue Nov 15 05:28:39 2016 From: winterkoninkje at gmail.com (wren romano) Date: Mon, 14 Nov 2016 21:28:39 -0800 Subject: =?UTF-8?B?UmU6IFByb3Bvc2FsOiBBZGQg4oCYdHlwZSBmIH4+IGcgPSBmb3JhbGwgYS4gZiBhIC0+IA==?= =?UTF-8?B?ZyBh4oCZ?= In-Reply-To: References: Message-ID: I agree too. I use the name (~>) whenever I have some profunctor-like type variable. Putting it in a library would be like defining "x" or "a" in a library. Certainly natural transformations are helpful to have a library around, but they should be given a better name. On Mon, Nov 14, 2016 at 1:48 PM, John Wiegley wrote: >>>>>> "EM" == Eric Mertens writes: > > EM> I'd prefer that we didn't prescribe a meaning to this generally useful > EM> type operator. This type synonym is very easy to define in any module > EM> where it's appropriate. > > I agree. Taking "~>" for natural transformations seems too specific. > > -- > John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F > http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries -- Live well, ~wren From david.feuer at gmail.com Tue Nov 15 05:37:17 2016 From: david.feuer at gmail.com (David Feuer) Date: Tue, 15 Nov 2016 00:37:17 -0500 Subject: Proposal: Add portable eliminator for Data.Type.Equality In-Reply-To: References: Message-ID: On Nov 15, 2016 12:24 AM, "wren romano" wrote: > > subst :: a :~: b -> f a -> f b > > subst Refl x = x > > I'm all for adding this function, but do note that the type is > suboptimal since GHC lacks general functions (and higher-order pattern > matching) at the type level. Which means we'll actually end up wanting > a family of different "subst" functions to cover all the (relevant) > cases the definition above would cover in a language like Agda, Coq, > etc. Yes, we will, but those can be written using `subst` and one or more auxiliary types without additional "primitive" eliminators (see below). > E.g., > > Prelude> let x :: Either Bool Int; x = Right 42 > > Prelude> :t (`subst` x) > (`subst` x) :: Int :~: b -> Either Bool b > > When I might've really wanted/meant (Bool :~: b -> Either b Int) We can write newtype Flip f x y = Flip { unFlip :: f y x } subst2 :: a :~: b -> f a x -> f b x subst2 eq = unFlip . subst eq . Flip The subst2 function will work on the left side of Either. -------------- next part -------------- An HTML attachment was scrubbed... URL: From oleg.grenrus at iki.fi Tue Nov 15 09:01:53 2016 From: oleg.grenrus at iki.fi (Oleg Grenrus) Date: Tue, 15 Nov 2016 11:01:53 +0200 Subject: =?utf-8?Q?Re=3A_Proposal=3A_Add_=E2=80=98type_f_=7E=3E_g_=3D_for?= =?utf-8?Q?all_a=2E_f_a_-=3E_g_a=E2=80=99?= In-Reply-To: References: Message-ID: <39F7FE10-DA2D-4253-BEAB-B6ABE41B2A2D@iki.fi> FWIW, i personally use `natural-transformation` library [1], which provides this exact type alias, and also newtype around it (which is occasionally useful). I’d rather promote the usage of the library (which has only `base` as dependency!). - [1]: https://hackage.haskell.org/package/natural-transformation-0.3.1/docs/Control-Natural.html > On 14 Nov 2016, at 20:11, Baldur Blöndal wrote: > > What the subject says, add > > type f ~> g = forall a. f a -> g a > > to ‘base’. Further motivation (and arguments against) in GHC Trac ticket 12772 [1]. > > [1] https://ghc.haskell.org/trac/ghc/ticket/12772 > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 842 bytes Desc: Message signed with OpenPGP using GPGMail URL: From oleg.grenrus at iki.fi Tue Nov 15 09:13:12 2016 From: oleg.grenrus at iki.fi (Oleg Grenrus) Date: Tue, 15 Nov 2016 11:13:12 +0200 Subject: Proposal: Add portable eliminator for Data.Type.Equality In-Reply-To: References: Message-ID: <996E7FBA-41D4-47DD-BEE6-CEC1EB681D7B@iki.fi> I’m -1 λ Prelude Data.Type.Equality > :t (`gcastWith` x) :: b :~: Bool -> Either b Int (`gcastWith` x) :: b :~: Bool -> Either b Int :: b :~: Bool -> Either b Int gcastWith :: (a :~: b) -> (a ~ b => r) -> r That type “unifies" with subst :: (a :~: b) -> c a -> c b (and is more “general”), if stare at it for long enough. - Oleg P.S. FWIW there is PR [1] to `eq` [2], if you want to play with Leibniz equality definition. - [1]: http://hackage.haskell.org/package/eq - [2]: https://github.com/ekmett/eq/pull/9/files > On 15 Nov 2016, at 07:37, David Feuer wrote: > > On Nov 15, 2016 12:24 AM, "wren romano" wrote: > > > subst :: a :~: b -> f a -> f b > > > subst Refl x = x > > > > I'm all for adding this function, but do note that the type is > > suboptimal since GHC lacks general functions (and higher-order pattern > > matching) at the type level. Which means we'll actually end up wanting > > a family of different "subst" functions to cover all the (relevant) > > cases the definition above would cover in a language like Agda, Coq, > > etc. > > Yes, we will, but those can be written using `subst` and one or more auxiliary types without additional "primitive" eliminators (see below). > > > E.g., > > > > Prelude> let x :: Either Bool Int; x = Right 42 > > > > Prelude> :t (`subst` x) > > (`subst` x) :: Int :~: b -> Either Bool b > > > > When I might've really wanted/meant (Bool :~: b -> Either b Int) > > We can write > > newtype Flip f x y = Flip { unFlip :: f y x } > > subst2 :: a :~: b -> f a x -> f b x > subst2 eq = unFlip . subst eq . Flip > > The subst2 function will work on the left side of Either. > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 842 bytes Desc: Message signed with OpenPGP using GPGMail URL: From ekmett at gmail.com Tue Nov 15 12:02:05 2016 From: ekmett at gmail.com (Edward Kmett) Date: Tue, 15 Nov 2016 07:02:05 -0500 Subject: =?UTF-8?B?UmU6IFByb3Bvc2FsOiBBZGQg4oCYdHlwZSBmIH4+IGcgPSBmb3JhbGwgYS4gZiBhIC0+IA==?= =?UTF-8?B?ZyBh4oCZ?= In-Reply-To: <39F7FE10-DA2D-4253-BEAB-B6ABE41B2A2D@iki.fi> References: <39F7FE10-DA2D-4253-BEAB-B6ABE41B2A2D@iki.fi> Message-ID: I'm -1 on the proposal of adding this type to base. One one hand, natural-transformation already provides this definition in a "centralized" locale for folks who really do want to share it with a ridiculously stripped down set of dependencies, which provides a place for those who really want to get it from a central location as well. Not as nice as no dependency at all in a world where we could all agree this is the best thing to add to base, but darn close. On the other: As a type alias there is no real compatibility gain to be had. If both of us define (~>) as above, then types written with types against my (~>) and types written against your (~>) are *freely interchangeable*, even if you might have to play with your import lists more carefully. We can't hang any instances off of it, so almost all of the standard arguments for moving it "closer to base" fail to take effect. On the other, other hand, something like newtype f ~> g = Nat { runNat :: forall a. f a -> g a } is slightly easier to make a case for, because you can hang instances off of it and share more than one line of code, but I'd be -1 on that as well, because there are a host of issues with that definition as well not being "one size fits all" either. There are several viable definitions for a natural transformation depending on how general you want to get -- and this one (like the one in natural-transformation) conflates parametricity with naturality, so rapidly stops being good enough as you drift into PolyKinds and then start wanting a more accurate Category and Functor notions, which then force you to parameterize over the underlying `->` in the definition. Both of these definitions occupy awkward suboptimal points in the design space, so I'd rather not see us locked into their use by enshrining either one in base. -Edward On Tue, Nov 15, 2016 at 4:01 AM, Oleg Grenrus wrote: > FWIW, i personally use `natural-transformation` library [1], which > provides this exact type alias, and also newtype around it (which is > occasionally useful). > > I’d rather promote the usage of the library (which has only `base` as > dependency!). > > - [1]: https://hackage.haskell.org/package/natural- > transformation-0.3.1/docs/Control-Natural.html > > On 14 Nov 2016, at 20:11, Baldur Blöndal wrote: > > What the subject says, add > > type f ~> g = forall a. f a -> g a > > to ‘base’. Further motivation (and arguments against) in GHC Trac ticket > 12772 [1]. > > [1] https://ghc.haskell.org/trac/ghc/ticket/12772 > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Tue Nov 15 20:09:54 2016 From: david.feuer at gmail.com (David Feuer) Date: Tue, 15 Nov 2016 15:09:54 -0500 Subject: Proposal: Add portable eliminator for Data.Type.Equality In-Reply-To: <996E7FBA-41D4-47DD-BEE6-CEC1EB681D7B@iki.fi> References: <996E7FBA-41D4-47DD-BEE6-CEC1EB681D7B@iki.fi> Message-ID: Yes, gcastWith is certainly "more general" than subst. Exporting subst from Data.Type.Equality would allow programmers to write code that doesn't *care* how :~: is represented. On Tue, Nov 15, 2016 at 4:13 AM, Oleg Grenrus wrote: > I’m -1 > > λ Prelude Data.Type.Equality > :t (`gcastWith` x) :: b :~: Bool -> Either b Int > (`gcastWith` x) :: b :~: Bool -> Either b Int > :: b :~: Bool -> Either b Int > > gcastWith :: (a :~: b) -> (a ~ b => r) -> r > > That type “unifies" with subst :: (a :~: b) -> c a -> c b (and is more “general”), if stare at it for long enough. > > - Oleg > > P.S. FWIW there is PR [1] to `eq` [2], if you want to play with Leibniz equality definition. > > - [1]: http://hackage.haskell.org/package/eq > - [2]: https://github.com/ekmett/eq/pull/9/files > >> On 15 Nov 2016, at 07:37, David Feuer wrote: >> >> On Nov 15, 2016 12:24 AM, "wren romano" wrote: >> > > subst :: a :~: b -> f a -> f b >> > > subst Refl x = x >> > >> > I'm all for adding this function, but do note that the type is >> > suboptimal since GHC lacks general functions (and higher-order pattern >> > matching) at the type level. Which means we'll actually end up wanting >> > a family of different "subst" functions to cover all the (relevant) >> > cases the definition above would cover in a language like Agda, Coq, >> > etc. >> >> Yes, we will, but those can be written using `subst` and one or more auxiliary types without additional "primitive" eliminators (see below). >> >> > E.g., >> > >> > Prelude> let x :: Either Bool Int; x = Right 42 >> > >> > Prelude> :t (`subst` x) >> > (`subst` x) :: Int :~: b -> Either Bool b >> > >> > When I might've really wanted/meant (Bool :~: b -> Either b Int) >> >> We can write >> >> newtype Flip f x y = Flip { unFlip :: f y x } >> >> subst2 :: a :~: b -> f a x -> f b x >> subst2 eq = unFlip . subst eq . Flip >> >> The subst2 function will work on the left side of Either. >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > From drkoster at qq.com Thu Nov 17 02:43:16 2016 From: drkoster at qq.com (winter) Date: Thu, 17 Nov 2016 10:43:16 +0800 Subject: Add ifThenElse and (?) to Data.Bool Message-ID: <6367E495-3C15-4768-BD82-7707CB7BC83D@qq.com> It seems this’s a very old request, see https://wiki.haskell.org/If-then-else . I’d like to see following: ifThenElse :: Bool -> a -> a -> a ifThenElse True x _ = x ifThenElse False _ y = y infixr 1 ? (?) :: Bool -> a -> a -> a (?) = ifThenElse in Date.Bool module, it will have advantages that: + It’s more composable than syntax. + Write (xxx ? yyy $ zzz) instead of (if xxx then yyy else zzz) is more consistent with (f . g $ x) style, and save key strokes. + In module with RebindableSyntax enabled, you can import ifThenElse to get default behavior. Whether or not to be exported by Prelude is another question, but Data.Bool seems a good place to start with. Cheers~ Winter -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Thu Nov 17 03:03:17 2016 From: david.feuer at gmail.com (David Feuer) Date: Wed, 16 Nov 2016 22:03:17 -0500 Subject: Add ifThenElse and (?) to Data.Bool In-Reply-To: <6367E495-3C15-4768-BD82-7707CB7BC83D@qq.com> References: <6367E495-3C15-4768-BD82-7707CB7BC83D@qq.com> Message-ID: If ifThenElse is good for RebindableSyntax, then I'm +1 on that (but I've never played with that extension, so I don't really know). I'm -1 on (?). We already have bool, which tends to be rather more useful when partially applied. On Nov 16, 2016 9:43 PM, "winter" wrote: > It seems this’s a very old request, see https://wiki.haskell.org/If-then-else. I’d like to see following: > > > ifThenElse :: Bool -> a -> a -> a > ifThenElse True x _ = xifThenElse False _ y = y > > > infixr 1 ?(?) :: Bool -> a -> a -> a(?) = ifThenElse > > > in Date.Bool module, it will have advantages that: > > > + It’s more composable than syntax. > > + Write (xxx ? yyy $ zzz) instead of (if xxx then yyy else zzz) is more consistent with (f . g $ x) style, and save key strokes. > > + In module with RebindableSyntax enabled, you can import ifThenElse to get default behavior. > > > Whether or not to be exported by Prelude is another question, but Data.Bool seems a good place to start with. > > > Cheers~ > > Winter > > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From m.farkasdyck at gmail.com Thu Nov 17 03:06:41 2016 From: m.farkasdyck at gmail.com (M Farkas-Dyck) Date: Wed, 16 Nov 2016 19:06:41 -0800 Subject: Add ifThenElse and (?) to Data.Bool In-Reply-To: <6367E495-3C15-4768-BD82-7707CB7BC83D@qq.com> References: <6367E495-3C15-4768-BD82-7707CB7BC83D@qq.com> Message-ID: Could we use `bool` rather than add a new term for RebindableSyntax? i.e. define if-then-else in terms of `bool`. From drkoster at qq.com Thu Nov 17 03:16:19 2016 From: drkoster at qq.com (winter) Date: Thu, 17 Nov 2016 11:16:19 +0800 Subject: Add ifThenElse and (?) to Data.Bool In-Reply-To: References: <6367E495-3C15-4768-BD82-7707CB7BC83D@qq.com> Message-ID: <567AE701-1827-4CD1-B164-5E4A3E1C5413@qq.com> I’m totally aware of the existence of bool, i suppose (?) is mainly used in fully application to get a different style than if-then-else syntax, say, ... isGoo <- checkGoo isGoo ? goo $ woo ... But like what the wiki suggested, (?) can be used in some high-order situations. I like this operator because the mnemonic of questioning meaning. > On 17 Nov 2016, at 11:03, David Feuer wrote: > > If ifThenElse is good for RebindableSyntax, then I'm +1 on that (but I've never played with that extension, so I don't really know). I'm -1 on (?). We already have bool, which tends to be rather more useful when partially applied. > > > On Nov 16, 2016 9:43 PM, "winter" > wrote: > It seems this’s a very old request, see https://wiki.haskell.org/If-then-else . I’d like to see following: > > ifThenElse :: Bool -> a -> a -> a > ifThenElse True x _ = x > ifThenElse False _ y = y > > infixr 1 ? > (?) :: Bool -> a -> a -> a > (?) = ifThenElse > > in Date.Bool module, it will have advantages that: > > + It’s more composable than syntax. > + Write (xxx ? yyy $ zzz) instead of (if xxx then yyy else zzz) is more consistent with (f . g $ x) style, and save key strokes. > + In module with RebindableSyntax enabled, you can import ifThenElse to get default behavior. > > Whether or not to be exported by Prelude is another question, but Data.Bool seems a good place to start with. > > Cheers~ > Winter > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Thu Nov 17 03:25:17 2016 From: david.feuer at gmail.com (David Feuer) Date: Wed, 16 Nov 2016 22:25:17 -0500 Subject: Add ifThenElse and (?) to Data.Bool In-Reply-To: References: <6367E495-3C15-4768-BD82-7707CB7BC83D@qq.com> Message-ID: If this rebindable syntax is about what I think it is, that would seem strange. bool is the Bool eliminator. It would seem weird to give it a type like, say, bool :: Monad m => m a -> m a -> m Bool -> m a On Nov 16, 2016 10:06 PM, "M Farkas-Dyck" wrote: > Could we use `bool` rather than add a new term for RebindableSyntax? > i.e. define if-then-else in terms of `bool`. > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ivan.miljenovic at gmail.com Thu Nov 17 03:49:22 2016 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Thu, 17 Nov 2016 14:49:22 +1100 Subject: Add ifThenElse and (?) to Data.Bool In-Reply-To: <6367E495-3C15-4768-BD82-7707CB7BC83D@qq.com> References: <6367E495-3C15-4768-BD82-7707CB7BC83D@qq.com> Message-ID: I'm -0.5 on ifThenElse (if it can be used with RebindableSyntax then someone may want to use it, though I personally find the bool function to be more than sufficient as I tend to find the "which branch do I choose" argument to be the last when constructing function pipelines), and -1 for the operator. On 17 November 2016 at 13:43, winter wrote: > It seems this’s a very old request, see > https://wiki.haskell.org/If-then-else. I’d like to see following: > > > ifThenElse :: Bool -> a -> a -> a > ifThenElse True x _ = x > ifThenElse False _ y = y > > > infixr 1 ? > (?) :: Bool -> a -> a -> a > (?) = ifThenElse > > > in Date.Bool module, it will have advantages that: > > > + It’s more composable than syntax. > > + Write (xxx ? yyy $ zzz) instead of (if xxx then yyy else zzz) is more > consistent with (f . g $ x) style, and save key strokes. > > + In module with RebindableSyntax enabled, you can import ifThenElse to get > default behavior. > > > Whether or not to be exported by Prelude is another question, but Data.Bool > seems a good place to start with. > > > Cheers~ > > Winter > > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -- Ivan Lazar Miljenovic Ivan.Miljenovic at gmail.com http://IvanMiljenovic.wordpress.com From drkoster at qq.com Thu Nov 17 04:01:20 2016 From: drkoster at qq.com (winter) Date: Thu, 17 Nov 2016 12:01:20 +0800 Subject: Add ifThenElse and (?) to Data.Bool In-Reply-To: <567AE701-1827-4CD1-B164-5E4A3E1C5413@qq.com> References: <6367E495-3C15-4768-BD82-7707CB7BC83D@qq.com> <567AE701-1827-4CD1-B164-5E4A3E1C5413@qq.com> Message-ID: <65585F69-68EB-49D2-95BD-FB11614385C0@qq.com> And here’s some other stuff i can came up with it(without obscured readability IMHO): ... -- replacement for ifM in various package, similar to (>>= when) (mFlag >>= (?)) flagEnabled -- mFlag :: Monad m => m Bool $ flagDisabled -- nicer if-then-else in applicative style (?) <$> fFlag <$> flagEnabled <*> flagDisabled -- compose with predicates to define your own if ifLower = (?) . isLower ifLower ‘X’ lower upper ... Basically it's a good if-then-else replacement if you’re comfortable with point-free style. > On 17 Nov 2016, at 11:16, winter wrote: > > I’m totally aware of the existence of bool, i suppose (?) is mainly used in fully application to get a different style than if-then-else syntax, say, > > ... > isGoo <- checkGoo > isGoo ? goo > $ woo > ... > > > But like what the wiki suggested, (?) can be used in some high-order situations. I like this operator because the mnemonic of questioning meaning. > > > >> On 17 Nov 2016, at 11:03, David Feuer > wrote: >> >> If ifThenElse is good for RebindableSyntax, then I'm +1 on that (but I've never played with that extension, so I don't really know). I'm -1 on (?). We already have bool, which tends to be rather more useful when partially applied. >> >> >> On Nov 16, 2016 9:43 PM, "winter" > wrote: >> It seems this’s a very old request, see https://wiki.haskell.org/If-then-else . I’d like to see following: >> >> ifThenElse :: Bool -> a -> a -> a >> ifThenElse True x _ = x >> ifThenElse False _ y = y >> >> infixr 1 ? >> (?) :: Bool -> a -> a -> a >> (?) = ifThenElse >> >> in Date.Bool module, it will have advantages that: >> >> + It’s more composable than syntax. >> + Write (xxx ? yyy $ zzz) instead of (if xxx then yyy else zzz) is more consistent with (f . g $ x) style, and save key strokes. >> + In module with RebindableSyntax enabled, you can import ifThenElse to get default behavior. >> >> Whether or not to be exported by Prelude is another question, but Data.Bool seems a good place to start with. >> >> Cheers~ >> Winter >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ekmett at gmail.com Thu Nov 17 04:02:10 2016 From: ekmett at gmail.com (Edward Kmett) Date: Wed, 16 Nov 2016 23:02:10 -0500 Subject: Add ifThenElse and (?) to Data.Bool In-Reply-To: <6367E495-3C15-4768-BD82-7707CB7BC83D@qq.com> References: <6367E495-3C15-4768-BD82-7707CB7BC83D@qq.com> Message-ID: I'm pretty strongly -1 on adding (?). It is one of the few single character operators available to the average user out of the box and this is a space where we already have established combinators. It is a valuable portion of the namespace to spend and each approach we offer means more inessential complexity to newcomers to the language. Given the existence of bool today I'm weakly -1 on ifThenElse. That said, if we were to add RebindableSyntax support for it, I think that I'd personally flip around to being in favor. It is a much more clear thing for RebindableSyntax to call out to than something called "bool" that comes with a different argument order. These are just my personal feelings on the matter, and not any sort of "cast in stone" CLC judgments. -Edward On Wed, Nov 16, 2016 at 9:43 PM, winter wrote: > It seems this’s a very old request, see https://wiki.haskell.org/If-then-else. I’d like to see following: > > > ifThenElse :: Bool -> a -> a -> a > ifThenElse True x _ = xifThenElse False _ y = y > > > infixr 1 ?(?) :: Bool -> a -> a -> a(?) = ifThenElse > > > in Date.Bool module, it will have advantages that: > > > + It’s more composable than syntax. > > + Write (xxx ? yyy $ zzz) instead of (if xxx then yyy else zzz) is more consistent with (f . g $ x) style, and save key strokes. > > + In module with RebindableSyntax enabled, you can import ifThenElse to get default behavior. > > > Whether or not to be exported by Prelude is another question, but Data.Bool seems a good place to start with. > > > Cheers~ > > Winter > > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ekmett at gmail.com Thu Nov 17 04:03:43 2016 From: ekmett at gmail.com (Edward Kmett) Date: Wed, 16 Nov 2016 23:03:43 -0500 Subject: Add ifThenElse and (?) to Data.Bool In-Reply-To: <65585F69-68EB-49D2-95BD-FB11614385C0@qq.com> References: <6367E495-3C15-4768-BD82-7707CB7BC83D@qq.com> <567AE701-1827-4CD1-B164-5E4A3E1C5413@qq.com> <65585F69-68EB-49D2-95BD-FB11614385C0@qq.com> Message-ID: (?) <$> fFlag <$> flagEnabled <*> flagDisabled You probably don't want this. This performs both effects (!), regardless of the flag, but only keeps one result. -Edward On Wed, Nov 16, 2016 at 11:01 PM, winter wrote: > And here’s some other stuff i can came up with it(without obscured > readability IMHO): > > ... > -- replacement for ifM in various package, similar to (>>= when) > > (mFlag >>= (?)) flagEnabled -- mFlag :: Monad m => m Bool > $ flagDisabled > > -- nicer if-then-else in applicative style > (?) <$> fFlag <$> flagEnabled > <*> flagDisabled > > -- compose with predicates to define your own if > ifLower = (?) . isLower > ifLower ‘X’ lower > upper > ... > > > Basically it's a good if-then-else replacement if you’re comfortable with > point-free style. > > > On 17 Nov 2016, at 11:16, winter wrote: > > I’m totally aware of the existence of bool, i suppose (?) is mainly used > in fully application to get a different style than if-then-else syntax, say, > > ... > isGoo <- checkGoo > isGoo ? goo > $ woo > ... > > > But like what the wiki suggested, (?) can be used in some high-order > situations. I like this operator because the mnemonic of questioning > meaning. > > > > On 17 Nov 2016, at 11:03, David Feuer wrote: > > If ifThenElse is good for RebindableSyntax, then I'm +1 on that (but I've > never played with that extension, so I don't really know). I'm -1 on (?). > We already have bool, which tends to be rather more useful when partially > applied. > > On Nov 16, 2016 9:43 PM, "winter" wrote: > >> It seems this’s a very old request, see https://wiki.haskell.org/If-then-else. I’d like to see following: >> >> >> ifThenElse :: Bool -> a -> a -> a >> ifThenElse True x _ = xifThenElse False _ y = y >> >> >> infixr 1 ?(?) :: Bool -> a -> a -> a(?) = ifThenElse >> >> >> in Date.Bool module, it will have advantages that: >> >> >> + It’s more composable than syntax. >> >> + Write (xxx ? yyy $ zzz) instead of (if xxx then yyy else zzz) is more consistent with (f . g $ x) style, and save key strokes. >> >> + In module with RebindableSyntax enabled, you can import ifThenElse to get default behavior. >> >> >> Whether or not to be exported by Prelude is another question, but Data.Bool seems a good place to start with. >> >> >> Cheers~ >> >> Winter >> >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> >> > > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From drkoster at qq.com Thu Nov 17 04:11:13 2016 From: drkoster at qq.com (winter) Date: Thu, 17 Nov 2016 12:11:13 +0800 Subject: Add ifThenElse and (?) to Data.Bool In-Reply-To: References: <6367E495-3C15-4768-BD82-7707CB7BC83D@qq.com> <567AE701-1827-4CD1-B164-5E4A3E1C5413@qq.com> <65585F69-68EB-49D2-95BD-FB11614385C0@qq.com> Message-ID: <862FB9BD-1F46-4128-8B27-4949DB52746B@qq.com> Ah Yeah, i see. It’s indeed a rare use case. From all your feedback, I guess i will make a package with (?) for someone who want to save keystrokes like me ;) Cheers~ Winter > On 17 Nov 2016, at 12:03, Edward Kmett wrote: > > (?) <$> fFlag <$> flagEnabled <*> flagDisabled > > You probably don't want this. This performs both effects (!), regardless of the flag, but only keeps one result. > > -Edward > > > On Wed, Nov 16, 2016 at 11:01 PM, winter > wrote: > And here’s some other stuff i can came up with it(without obscured readability IMHO): > > ... > -- replacement for ifM in various package, similar to (>>= when) > > (mFlag >>= (?)) flagEnabled -- mFlag :: Monad m => m Bool > $ flagDisabled > > -- nicer if-then-else in applicative style > (?) <$> fFlag <$> flagEnabled > <*> flagDisabled > > -- compose with predicates to define your own if > ifLower = (?) . isLower > ifLower ‘X’ lower > upper > ... > > > Basically it's a good if-then-else replacement if you’re comfortable with point-free style. > > >> On 17 Nov 2016, at 11:16, winter > wrote: >> >> I’m totally aware of the existence of bool, i suppose (?) is mainly used in fully application to get a different style than if-then-else syntax, say, >> >> ... >> isGoo <- checkGoo >> isGoo ? goo >> $ woo >> ... >> >> >> But like what the wiki suggested, (?) can be used in some high-order situations. I like this operator because the mnemonic of questioning meaning. >> >> >> >>> On 17 Nov 2016, at 11:03, David Feuer > wrote: >>> >>> If ifThenElse is good for RebindableSyntax, then I'm +1 on that (but I've never played with that extension, so I don't really know). I'm -1 on (?). We already have bool, which tends to be rather more useful when partially applied. >>> >>> >>> On Nov 16, 2016 9:43 PM, "winter" > wrote: >>> It seems this’s a very old request, see https://wiki.haskell.org/If-then-else . I’d like to see following: >>> >>> ifThenElse :: Bool -> a -> a -> a >>> ifThenElse True x _ = x >>> ifThenElse False _ y = y >>> >>> infixr 1 ? >>> (?) :: Bool -> a -> a -> a >>> (?) = ifThenElse >>> >>> in Date.Bool module, it will have advantages that: >>> >>> + It’s more composable than syntax. >>> + Write (xxx ? yyy $ zzz) instead of (if xxx then yyy else zzz) is more consistent with (f . g $ x) style, and save key strokes. >>> + In module with RebindableSyntax enabled, you can import ifThenElse to get default behavior. >>> >>> Whether or not to be exported by Prelude is another question, but Data.Bool seems a good place to start with. >>> >>> Cheers~ >>> Winter >>> >>> _______________________________________________ >>> Libraries mailing list >>> Libraries at haskell.org >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >>> >> > > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From lemming at henning-thielemann.de Thu Nov 17 08:36:39 2016 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Thu, 17 Nov 2016 09:36:39 +0100 (CET) Subject: Add ifThenElse and (?) to Data.Bool In-Reply-To: <862FB9BD-1F46-4128-8B27-4949DB52746B@qq.com> References: <6367E495-3C15-4768-BD82-7707CB7BC83D@qq.com> <567AE701-1827-4CD1-B164-5E4A3E1C5413@qq.com> <65585F69-68EB-49D2-95BD-FB11614385C0@qq.com> <862FB9BD-1F46-4128-8B27-4949DB52746B@qq.com> Message-ID: On Thu, 17 Nov 2016, winter wrote: > Ah Yeah, i see. It’s indeed a rare use case. > From all your feedback, I guess i will make a package with (?) for someone who want to save keystrokes like me ;) I use if' and (?:) from https://hackage.haskell.org/package/utility-ht-0.0.12/docs/Data-Bool-HT.html E.g. this is very handy: if' (even n) "even" $ if' (isPrime n) "prime" $ "boring" (?:) is the uncurried variant of (?). I do not see value in curried (?) because I can just use `if'` then (which I never did). From gale at sefer.org Thu Nov 17 10:14:44 2016 From: gale at sefer.org (Yitzchak Gale) Date: Thu, 17 Nov 2016 12:14:44 +0200 Subject: Add ifThenElse and (?) to Data.Bool In-Reply-To: References: <6367E495-3C15-4768-BD82-7707CB7BC83D@qq.com> Message-ID: Edward Kmett wrote: > I'm pretty strongly -1 on adding (?)... > we already have established combinators... > more inessential > complexity to newcomers to the language. I'm not so worried about that if it's not in the Prelude. I doubt that this would get wide usage. And if it does, then maybe that is better use of the namespace real estate. I am 0 on (?). I probably would never use it. I am -1 on ifThenElse. We already have bool. Some of our developers use it all the time and it's fine. It's not like "map" and "for" which have common idioms where parameter order really matters. Other than that, we shouldn't litter the libraries with flipped versions of everything. Anyway, bool is the natural parameter order in Haskell. I'll make more explicit what others have already said, with this analogy: maybe (if it fails) (if it succeeds) (input data) either (if it fails) (if it succeeds) (input data) foldl (if it's null) (if it's not null) (input data) foldr (if it's null) (if it's not null) (input data) Whereas Haskell's if-then-else syntax is awkward. Some people (not me) even say it should never be used at all. And so bool (if it fails) (if it succeeds) (input data) makes the most sense. -Yitz From lemming at henning-thielemann.de Thu Nov 17 10:19:55 2016 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Thu, 17 Nov 2016 11:19:55 +0100 (CET) Subject: Add ifThenElse and (?) to Data.Bool In-Reply-To: References: <6367E495-3C15-4768-BD82-7707CB7BC83D@qq.com> Message-ID: On Thu, 17 Nov 2016, Yitzchak Gale wrote: > Anyway, bool is the natural parameter order in Haskell. > I'll make more explicit what others have already said, with > this analogy: > > maybe (if it fails) (if it succeeds) (input data) > either (if it fails) (if it succeeds) (input data) > foldl (if it's null) (if it's not null) (input data) > foldr (if it's null) (if it's not null) (input data) Unfortunately, it is the other way round: foldl (if it's not null) (if it's null) (input data) foldr (if it's not null) (if it's null) (input data) From drkoster at qq.com Thu Nov 17 12:19:17 2016 From: drkoster at qq.com (winter) Date: Thu, 17 Nov 2016 20:19:17 +0800 Subject: Add ifThenElse and (?) to Data.Bool In-Reply-To: References: <6367E495-3C15-4768-BD82-7707CB7BC83D@qq.com> Message-ID: <6E4193EC-502A-4A99-8D16-0A9C0C312852@qq.com> I decide to make a standalone package: http://hackage.haskell.org/package/if Cheers! Winter > On 17 Nov 2016, at 18:19, Henning Thielemann wrote: > > > On Thu, 17 Nov 2016, Yitzchak Gale wrote: > >> Anyway, bool is the natural parameter order in Haskell. >> I'll make more explicit what others have already said, with >> this analogy: >> >> maybe (if it fails) (if it succeeds) (input data) >> either (if it fails) (if it succeeds) (input data) > >> foldl (if it's null) (if it's not null) (input data) >> foldr (if it's null) (if it's not null) (input data) > > Unfortunately, it is the other way round: > > foldl (if it's not null) (if it's null) (input data) > foldr (if it's not null) (if it's null) (input data) > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries -------------- next part -------------- An HTML attachment was scrubbed... URL: From eacameron at gmail.com Thu Nov 17 14:41:36 2016 From: eacameron at gmail.com (Elliot Cameron) Date: Thu, 17 Nov 2016 09:41:36 -0500 Subject: Add ifThenElse and (?) to Data.Bool In-Reply-To: <6E4193EC-502A-4A99-8D16-0A9C0C312852@qq.com> References: <6367E495-3C15-4768-BD82-7707CB7BC83D@qq.com> <6E4193EC-502A-4A99-8D16-0A9C0C312852@qq.com> Message-ID: FWIW, Winter, I sorta like that operator and it is even readable to people who use C, JS, etc. Thanks for the library. :) ᐧ On Thu, Nov 17, 2016 at 7:19 AM, winter wrote: > I decide to make a standalone package: http://hackage. > haskell.org/package/if > > Cheers! > Winter > > On 17 Nov 2016, at 18:19, Henning Thielemann < > lemming at henning-thielemann.de> wrote: > > > On Thu, 17 Nov 2016, Yitzchak Gale wrote: > > Anyway, bool is the natural parameter order in Haskell. > I'll make more explicit what others have already said, with > this analogy: > > maybe (if it fails) (if it succeeds) (input data) > either (if it fails) (if it succeeds) (input data) > > > foldl (if it's null) (if it's not null) (input data) > foldr (if it's null) (if it's not null) (input data) > > > Unfortunately, it is the other way round: > > foldl (if it's not null) (if it's null) (input data) > foldr (if it's not null) (if it's null) (input data) > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From baldurpet at gmail.com Thu Nov 17 22:45:36 2016 From: baldurpet at gmail.com (=?UTF-8?Q?Baldur_Bl=C3=B6ndal?=) Date: Thu, 17 Nov 2016 22:45:36 +0000 Subject: Add default MonadPlus or Alternative method to MonadFail Message-ID: The documentation for Control.Monad.Fail notes > If your Monad is also MonadPlus, a popular definition is >> fail _ = mzero This could be made a default definition for MonadPlus or Alternative > class Monad m => MonadFail m where > fail :: String -> m a > fail = const empty > default fail :: Alternative m => String -> m a This simplifies instances like [] and Maybe > instance MonadFail [] > instance MonadFail Maybe -------------- next part -------------- An HTML attachment was scrubbed... URL: From baldurpet at gmail.com Sun Nov 20 17:47:36 2016 From: baldurpet at gmail.com (=?UTF-8?Q?Baldur_Bl=C3=B6ndal?=) Date: Sun, 20 Nov 2016 17:47:36 +0000 Subject: Pattern synonyms and record fields for Cont, Writer, Reader, State, ... Message-ID: This will look like the original definitions [1] > newtype State s a = State { runState :: s -> (a, s) } before they became type synonyms > type State s = StateT s Identity by defining pattern synonyms > pattern State :: (s -> (a, s)) -> State s a > pattern State {runState} <- S.runState -> runState > where State a = state a Trac ticket #12767 for further information. [2] [1] http://book.realworldhaskell.org/read/monads.html#id643643 [2] https://ghc.haskell.org/trac/ghc/ticket/12767 -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Sun Nov 20 17:56:52 2016 From: david.feuer at gmail.com (David Feuer) Date: Sun, 20 Nov 2016 12:56:52 -0500 Subject: Pattern synonyms and record fields for Cont, Writer, Reader, State, ... In-Reply-To: References: Message-ID: This sounds fantastic! I think it is very important to provide sufficient documentation in the source to allow newish users who click through to understand as much as they need. On Nov 20, 2016 12:47 PM, "Baldur Blöndal" wrote: > This will look like the original definitions [1] > > > newtype State s a = State { runState :: s -> (a, s) } > > before they became type synonyms > > > type State s = StateT s Identity > > by defining pattern synonyms > > > pattern State :: (s -> (a, s)) -> State s a > > pattern State {runState} <- S.runState -> runState > > where State a = state a > > Trac ticket #12767 for further information. [2] > > [1] http://book.realworldhaskell.org/read/monads.html#id643643 > [2] https://ghc.haskell.org/trac/ghc/ticket/12767 > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mail at joachim-breitner.de Mon Nov 21 18:29:10 2016 From: mail at joachim-breitner.de (Joachim Breitner) Date: Mon, 21 Nov 2016 13:29:10 -0500 Subject: Add ifThenElse and (?) to Data.Bool In-Reply-To: <6367E495-3C15-4768-BD82-7707CB7BC83D@qq.com> References: <6367E495-3C15-4768-BD82-7707CB7BC83D@qq.com> Message-ID: <1479752950.18936.18.camel@joachim-breitner.de> Hi, Am Donnerstag, den 17.11.2016, 10:43 +0800 schrieb winter: > It seems this’s a very old request, see https://wiki.haskell.org/If-t > hen-else. I’d like to see following: > > ifThenElse :: Bool -> a -> a -> a > ifThenElse True  x _ = x > ifThenElse False _ y = y +1 on that. It is strange that GHC desugars to ifThenElse¹ without this function being available anywhere. Most (all?) of the other rebindable syntax elements work out of the box as before with Prelude imported but this one. Therefore, I’d support a proposal to add ifThenElse to the prelude. It would also make teaching nicer, by pointing students to this function and saying „if then else is just syntactic sugar for it“. Slightly better than „if then else is just syntactic sugar for a hypothetical function that you can define, but that is not there.“ > infixr 1 ? > (?) :: Bool -> a -> a -> a > (?) = ifThenElse -1. Operators are just too scarce. Greetings, Joachim ¹ http://downloads.haskell.org/~ghc/8.0.1/docs/html/users_guide/glasgow _exts.html#rebindable-syntax-and-the-implicit-prelude-import -- Joachim “nomeata” Breitner   mail at joachim-breitner.de • https://www.joachim-breitner.de/   XMPP: nomeata at joachim-breitner.de • OpenPGP-Key: 0xF0FBF51F   Debian Developer: nomeata at debian.org -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: This is a digitally signed message part URL: From lemming at henning-thielemann.de Mon Nov 21 18:33:01 2016 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Mon, 21 Nov 2016 19:33:01 +0100 (CET) Subject: Add ifThenElse and (?) to Data.Bool In-Reply-To: <1479752950.18936.18.camel@joachim-breitner.de> References: <6367E495-3C15-4768-BD82-7707CB7BC83D@qq.com> <1479752950.18936.18.camel@joachim-breitner.de> Message-ID: On Mon, 21 Nov 2016, Joachim Breitner wrote: > It would also make teaching nicer, by pointing students to this > function and saying „if then else is just syntactic sugar for it“. > Slightly better than „if then else is just syntactic sugar for a > hypothetical function that you can define, but that is not there.“ One implementation is there: http://hackage.haskell.org/package/utility-ht-0.0.12/docs/Data-Bool-HT.html#v:ifThenElse if you want to point the students somewhere. :-) From baldurpet at gmail.com Mon Nov 21 22:52:46 2016 From: baldurpet at gmail.com (=?UTF-8?Q?Baldur_Bl=C3=B6ndal?=) Date: Mon, 21 Nov 2016 22:52:46 +0000 Subject: Remove redundant Functor constraint from StateT Applicative/Alternative instances Message-ID: Does this belong here? Applicative [1] and Alternative [2] instances of StateT have redundant constraints > instance (Functor m, Monad m) => Applicative (StateT s m) > instance (Functor m, MonadPlus m) => Alternative (StateT s m) The Functor constraint may be removed [1] https://hackage.haskell.org/package/transformers-0.5.2.0/docs/src/Control.Monad.Trans.State.Lazy.html#line-201 [2] https://hackage.haskell.org/package/transformers-0.5.2.0/docs/src/Control.Monad.Trans.State.Lazy.html#line-210 -------------- next part -------------- An HTML attachment was scrubbed... URL: From lemming at henning-thielemann.de Mon Nov 21 22:57:29 2016 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Mon, 21 Nov 2016 23:57:29 +0100 (CET) Subject: Remove redundant Functor constraint from StateT Applicative/Alternative instances In-Reply-To: References: Message-ID: On Mon, 21 Nov 2016, Baldur Blöndal wrote: > Does this belong here? Applicative [1] and Alternative [2] instances of StateT have redundant constraints > > > instance (Functor m, Monad     m) => Applicative (StateT s m) > > instance (Functor m, MonadPlus m) => Alternative (StateT s m) > > The Functor constraint may be removed Only since the AMP, i.e. GHC-7.10. From ekmett at gmail.com Tue Nov 22 08:56:12 2016 From: ekmett at gmail.com (Edward Kmett) Date: Tue, 22 Nov 2016 03:56:12 -0500 Subject: Remove redundant Functor constraint from StateT Applicative/Alternative instances In-Reply-To: References: Message-ID: They could be CPP'd around on newer versions, sure, at the cost of a fair bit of noise in the source code. Presumably it was considered simpler to just have one type signature. I've CC'd Ross Paterson, the maintainer of transformers. Ultimately it comes down to a 3 way decision between 1.) cleaner code by keeping the status quo, or 2.) cleaner haddocks by changing the code as requested here conditionally with CPP, or 3.) loss of backwards compatibility by just changing the type completely. I don't particularly care which of the first two options are taken -- and the first even has the benefit of requiring zero labor -- but I think it'd be a bad idea to lose backwards compatibility by taking the third. -Edward On Mon, Nov 21, 2016 at 5:52 PM, Baldur Blöndal wrote: > Does this belong here? Applicative [1] and Alternative [2] instances of > StateT have redundant constraints > > > instance (Functor m, Monad m) => Applicative (StateT s m) > > instance (Functor m, MonadPlus m) => Alternative (StateT s m) > > The Functor constraint may be removed > > [1] https://hackage.haskell.org/package/transformers-0.5.2.0/ > docs/src/Control.Monad.Trans.State.Lazy.html#line-201 > [2] https://hackage.haskell.org/package/transformers-0.5.2.0/ > docs/src/Control.Monad.Trans.State.Lazy.html#line-210 > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From baldurpet at gmail.com Tue Nov 22 09:17:32 2016 From: baldurpet at gmail.com (=?UTF-8?Q?Baldur_Bl=C3=B6ndal?=) Date: Tue, 22 Nov 2016 09:17:32 +0000 Subject: Remove redundant Functor constraint from StateT Applicative/Alternative instances In-Reply-To: References: Message-ID: 1) is good, I assume 3) will happen once the dust settles on AMP 2016-11-22 8:56 GMT+00:00 Edward Kmett : > They could be CPP'd around on newer versions, sure, at the cost of a fair > bit of noise in the source code. Presumably it was considered simpler to > just have one type signature. I've CC'd Ross Paterson, the maintainer of > transformers. Ultimately it comes down to a 3 way decision between 1.) > cleaner code by keeping the status quo, or 2.) cleaner haddocks by changing > the code as requested here conditionally with CPP, or 3.) loss of backwards > compatibility by just changing the type completely. > > I don't particularly care which of the first two options are taken -- and > the first even has the benefit of requiring zero labor -- but I think it'd > be a bad idea to lose backwards compatibility by taking the third. > > -Edward > > > On Mon, Nov 21, 2016 at 5:52 PM, Baldur Blöndal > wrote: > >> Does this belong here? Applicative [1] and Alternative [2] instances of >> StateT have redundant constraints >> >> > instance (Functor m, Monad m) => Applicative (StateT s m) >> > instance (Functor m, MonadPlus m) => Alternative (StateT s m) >> >> The Functor constraint may be removed >> >> [1] https://hackage.haskell.org/package/transformers-0.5.2.0/doc >> s/src/Control.Monad.Trans.State.Lazy.html#line-201 >> [2] https://hackage.haskell.org/package/transformers-0.5.2.0/doc >> s/src/Control.Monad.Trans.State.Lazy.html#line-210 >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From baldurpet at gmail.com Tue Nov 22 21:07:08 2016 From: baldurpet at gmail.com (=?UTF-8?Q?Baldur_Bl=C3=B6ndal?=) Date: Tue, 22 Nov 2016 21:07:08 +0000 Subject: Pattern synonyms and record fields for Cont, Writer, Reader, State, ... In-Reply-To: References: Message-ID: This [1] was posted 5 hours ago [1] https://www.reddit.com/r/haskellquestions/comments/5ebepq/perhaps_i_meant_one_of_these_statet/ 2016-11-20 17:56 GMT+00:00 David Feuer : > This sounds fantastic! I think it is very important to provide sufficient > documentation in the source to allow newish users who click through to > understand as much as they need. > > On Nov 20, 2016 12:47 PM, "Baldur Blöndal" wrote: > >> This will look like the original definitions [1] >> >> > newtype State s a = State { runState :: s -> (a, s) } >> >> before they became type synonyms >> >> > type State s = StateT s Identity >> >> by defining pattern synonyms >> >> > pattern State :: (s -> (a, s)) -> State s a >> > pattern State {runState} <- S.runState -> runState >> > where State a = state a >> >> Trac ticket #12767 for further information. [2] >> >> [1] http://book.realworldhaskell.org/read/monads.html#id643643 >> [2] https://ghc.haskell.org/trac/ghc/ticket/12767 >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From R.Paterson at city.ac.uk Wed Nov 23 01:02:24 2016 From: R.Paterson at city.ac.uk (Ross Paterson) Date: Wed, 23 Nov 2016 01:02:24 +0000 Subject: Remove redundant Functor constraint from StateT Applicative/Alternative instances In-Reply-To: References: Message-ID: <20161123010224.o2ty3g2gd5ehygra@city.ac.uk> On Tue, Nov 22, 2016 at 09:17:32AM +0000, Baldur Blöndal wrote: > 1) is good, I assume 3) will happen once the dust settles on AMP Yes, there's a lot of conditional CPP in there already, but this doesn't seem severe enough to justify more. > 2016-11-22 8:56 GMT+00:00 Edward Kmett : > > They could be CPP'd around on newer versions, sure, at the cost of a fair > bit of noise in the source code. Presumably it was considered simpler to > just have one type signature. I've CC'd Ross Paterson, the maintainer of > transformers. Ultimately it comes down to a 3 way decision between 1.) > cleaner code by keeping the status quo, or 2.) cleaner haddocks by changing > the code as requested here conditionally with CPP, or 3.) loss of backwards > compatibility by just changing the type completely. > > I don't particularly care which of the first two options are taken -- and > the first even has the benefit of requiring zero labor -- but I think it'd > be a bad idea to lose backwards compatibility by taking the third. > > -Edward > > > On Mon, Nov 21, 2016 at 5:52 PM, Baldur Blöndal > wrote: > > Does this belong here? Applicative [1] and Alternative [2] instances of > StateT have redundant constraints > > > instance (Functor m, Monad m) => Applicative (StateT s m) > > instance (Functor m, MonadPlus m) => Alternative (StateT s m) > > The Functor constraint may be removed > > [1] https://hackage.haskell.org/package/transformers-0.5.2.0/docs/src/ > Control.Monad.Trans.State.Lazy.html#line-201 > [2] https://hackage.haskell.org/package/transformers-0.5.2.0/docs/src/ > Control.Monad.Trans.State.Lazy.html#line-210 > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > > > > From david.feuer at gmail.com Thu Nov 24 02:55:25 2016 From: david.feuer at gmail.com (David Feuer) Date: Wed, 23 Nov 2016 21:55:25 -0500 Subject: The lazy Show instance for GHC.Generics.U1 is confusing. Message-ID: I was messing around in GHCi, exploring the generic representation of a particular value. I tried out both case testSequence of IxSequence x -> case from x of M1 (L1 y) -> y and case testSequence of IxSequence x -> case from x of M1 (R1 y) -> y I was initially mystified to see that neither of these produced an error. Surely, I thought, it can't be both L1 and R1! And indeed it can't. But the Show instance for U1 is lazy, so the first test happily printed out M1 {unM1 = U1} even though that is utter nonsense. I propose that U1 simply derive the Show instance to avoid such peculiar behavior. David Feuer From baldurpet at gmail.com Sun Nov 27 07:10:27 2016 From: baldurpet at gmail.com (=?UTF-8?Q?Baldur_Bl=C3=B6ndal?=) Date: Sun, 27 Nov 2016 07:10:27 +0000 Subject: Many functions can be generalised Message-ID: A year ago Edwardk Kmett pointed out some possible generalizations of functions [1], I made a ticket about them that led me here [2]. In addition to the functions mentioned > maybeToList :: Foldable f => f a -> [a] > maybeToList = toList > catMaybes :: (Foldable f) => f (Maybe a) -> [a] > catMaybes :: (Foldable f, Foldable g) => f (g a) -> [a] > catMaybes = foldMap toList > mapMaybes :: (a -> Maybe b) -> (forall f. Foldable f => f a -> [b]) > mapMaybes :: Foldable m => (a -> m b) -> (forall f. Foldable f => f a -> [b]) > mapMaybes f = foldMap (toList . f) we also have *many* other functions (I do not propose generalising all these function ((especially when the name stops making sense)), but I will include them) that I will define in the vocabulary of ‘lens’. Some generalise to ‘Foldable’ > take :: Int -> (forall f a. Foldable f => f a -> [a]) > take n = toListOf (taking n folded) > drop :: Int -> (forall f a. Foldable f => f a -> [a]) > drop n = toListOf (dropping n folded) > takeWhile :: (a -> Bool) -> (forall f. Foldable f => f a -> [a]) > takeWhile p = toListOf (takingWhile p folded) > dropWhile :: (a -> Bool) -> (forall f. Foldable f => f a -> [a]) > dropWhile p = toListOf (droppingWhile p folded) > -- Same as ‘Control.Lens.Indexed.None’ > filter :: (a -> Bool) -> (forall f. Foldable f => f a -> [a]) > filter p = toListOf (folded.filtered p) > cycle :: Foldable f => f a -> [a] > cycle = toListOf (cycled folded) > lookup :: Eq k => k -> (forall f. Foldable f => f (k, v) -> Maybe v) > lookup = lookupOf folded > listToMaybe :: Foldable f => f a -> Maybe a > listToMaybe = firstOf folded while others — to ‘Traversable’ > transpose :: Traversable f => f [b] -> [f b] > transpose = transposeOf traverse > scanl1 :: (a -> a -> a) -> (forall f. Traversable f => f a -> f a) > scanl1 = scanl1Of traverse > scanr1_ :: (a -> a -> a) -> (forall f. Traversable f => f a -> f a) > scanr1_ = scanr1Of traverse More radical suggestions (pay no heed to the hacky ‘partsOf’, assume better implementation [3]) would allow us to sort a ‘data V2 a = V2 a a deriving (…, Traversable)’ if it contains ordered values: > sort :: (Traversable t, Ord a) => t a -> t a > sort = over (partsOf traverse) Data.List.sort > sortBy :: (a -> a -> Ordering) -> ([a] -> [a]) > sortBy = over (partsOf traverse) . Data.List.sortBy > sortOn :: Ord b => (a -> b) -> ([a] -> [a]) > sortOn = over (partsOf traverse) . Data.List.sortOn > reverse :: Traversable t => t a -> t a > reverse = over (partsOf traverse) Data.List.reverse > -- Based on ‘Control.Lens.??’ > flip :: Functor f => f (a -> b) -> a -> f b > flip f x = fmap ($ x) f or > flip :: (Functor f, Distributive g) => f (g a) -> g (f a) > flip = Data.Distributive.distribute AMP happened some years ago, does this go too far or not far enough? ;) share your thoughts P.s. I understand those skeptical of the ‘partsOf’ solutions but they do feel magical and uses crop up in odd places, especially in compound structures (I don't have better examples): > ghci> peopleList = Pair ["Bob", "Eve"] (Just "Alice") > ghci> data Product f g a = Pair (f a) (g a) deriving (Show, Functor, Foldable, Traversable) > ghci> sort peopleList > Pair ["Alice","Bob"] (Just "Eve") > ghci> reverse peopleList > Pair ["Alice","Eve"] (Just "Bob") > ghci> peopleMap = fromList [(1,"Bob"),(2,"Eve"),(3,"Alice")] > ghci> sort peopleMap > fromList [(1,"Alice"),(2,"Bob"),(3,"Eve")] > ghci> reverse peopleMap > fromList [(1,"Alice"),(2,"Eve"),(3,"Bob")] [1] https://www.reddit.com/r/haskell/comments/2y2pe5/shouldnt_ftp_propagate_changes_over_the_entire/cp6vpb4/ [2] https://ghc.haskell.org/trac/ghc/ticket/12828 [3] http://stackoverflow.com/a/33320155/165806 -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Sun Nov 27 07:53:56 2016 From: david.feuer at gmail.com (David Feuer) Date: Sun, 27 Nov 2016 02:53:56 -0500 Subject: Many functions can be generalised In-Reply-To: References: Message-ID: I disagree with many of these. For example, I think of takeWhile as having a type shaped like takeWhile :: (a -> Bool) -> f a -> f a Implementations are available for, e.g., sequences, sets, and maps. I don't really want some silly list producer. If I want takeWhile.toList, I know where to get it. Similarly, if I want distribute (which I haven't yet), I know where to get it. Some of these proposals also have substantial performance penalties, such as the sort generalization (which also can't be written in an "obviously total" manner, unfortunately). On Nov 27, 2016 2:10 AM, "Baldur Blöndal" wrote: > A year ago Edwardk Kmett pointed out some possible generalizations of > functions [1], I made a ticket about them that led me here [2]. In addition > to the functions mentioned > > > maybeToList :: Foldable f => f a -> [a] > > maybeToList = toList > > > catMaybes :: (Foldable f) => f (Maybe a) -> [a] > > catMaybes :: (Foldable f, Foldable g) => f (g a) -> [a] > > catMaybes = foldMap toList > > > mapMaybes :: (a -> Maybe b) -> (forall f. Foldable f => f > a -> [b]) > > mapMaybes :: Foldable m => (a -> m b) -> (forall f. Foldable f => f > a -> [b]) > > mapMaybes f = foldMap (toList . f) > > we also have *many* other functions (I do not propose generalising all > these function ((especially when the name stops making sense)), but I will > include them) that I will define in the vocabulary of ‘lens’. Some > generalise to ‘Foldable’ > > > take :: Int -> (forall f a. Foldable f => f a -> [a]) > > take n = toListOf (taking n folded) > > > drop :: Int -> (forall f a. Foldable f => f a -> [a]) > > drop n = toListOf (dropping n folded) > > > takeWhile :: (a -> Bool) -> (forall f. Foldable f => f a -> [a]) > > takeWhile p = toListOf (takingWhile p folded) > > > dropWhile :: (a -> Bool) -> (forall f. Foldable f => f a -> [a]) > > dropWhile p = toListOf (droppingWhile p folded) > > > -- Same as ‘Control.Lens.Indexed.None’ > > filter :: (a -> Bool) -> (forall f. Foldable f => f a -> [a]) > > filter p = toListOf (folded.filtered p) > > > cycle :: Foldable f => f a -> [a] > > cycle = toListOf (cycled folded) > > > lookup :: Eq k => k -> (forall f. Foldable f => f (k, v) -> Maybe v) > > lookup = lookupOf folded > > > listToMaybe :: Foldable f => f a -> Maybe a > > listToMaybe = firstOf folded > > while others — to ‘Traversable’ > > > transpose :: Traversable f => f [b] -> [f b] > > transpose = transposeOf traverse > > > scanl1 :: (a -> a -> a) -> (forall f. Traversable f => f a -> f a) > > scanl1 = scanl1Of traverse > > > scanr1_ :: (a -> a -> a) -> (forall f. Traversable f => f a -> f a) > > scanr1_ = scanr1Of traverse > > More radical suggestions (pay no heed to the hacky ‘partsOf’, assume > better implementation [3]) would allow us to sort a ‘data V2 a = V2 a a > deriving (…, Traversable)’ if it contains ordered values: > > > sort :: (Traversable t, Ord a) => t a -> t a > > sort = over (partsOf traverse) Data.List.sort > > > sortBy :: (a -> a -> Ordering) -> ([a] -> [a]) > > sortBy = over (partsOf traverse) . Data.List.sortBy > > > sortOn :: Ord b => (a -> b) -> ([a] -> [a]) > > sortOn = over (partsOf traverse) . Data.List.sortOn > > > reverse :: Traversable t => t a -> t a > > reverse = over (partsOf traverse) Data.List.reverse > > > -- Based on ‘Control.Lens.??’ > > flip :: Functor f => f (a -> b) -> a -> f b > > flip f x = fmap ($ x) f > > or > > > flip :: (Functor f, Distributive g) => f (g a) -> g (f a) > > flip = Data.Distributive.distribute > > AMP happened some years ago, does this go too far or not far enough? ;) > share your thoughts > > P.s. I understand those skeptical of the ‘partsOf’ solutions but they do > feel magical and uses crop up in odd places, especially in compound > structures (I don't have better examples): > > > ghci> peopleList = Pair ["Bob", "Eve"] (Just "Alice") > > ghci> data Product f g a = Pair (f a) (g a) deriving (Show, Functor, > Foldable, Traversable) > > ghci> sort peopleList > > Pair ["Alice","Bob"] (Just "Eve") > > ghci> reverse peopleList > > Pair ["Alice","Eve"] (Just "Bob") > > > ghci> peopleMap = fromList [(1,"Bob"),(2,"Eve"),(3,"Alice")] > > ghci> sort peopleMap > > fromList [(1,"Alice"),(2,"Bob"),(3,"Eve")] > > ghci> reverse peopleMap > > fromList [(1,"Alice"),(2,"Eve"),(3,"Bob")] > > [1] https://www.reddit.com/r/haskell/comments/2y2pe5/ > shouldnt_ftp_propagate_changes_over_the_entire/cp6vpb4/ > [2] https://ghc.haskell.org/trac/ghc/ticket/12828 > [3] http://stackoverflow.com/a/33320155/165806 > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From amindfv at gmail.com Sun Nov 27 17:40:21 2016 From: amindfv at gmail.com (amindfv at gmail.com) Date: Sun, 27 Nov 2016 11:40:21 -0600 Subject: Many functions can be generalised In-Reply-To: References: Message-ID: <0EBAE5AD-3E9C-4F78-AB00-9820A613039C@gmail.com> I'd also be -1. Function generalization sometimes has a cost in comprehensability, and there aren't enough benefits to make it worth it to me. Tom > El 27 nov 2016, a las 01:53, David Feuer escribió: > > I disagree with many of these. For example, I think of takeWhile as having a type shaped like > > takeWhile :: (a -> Bool) -> f a -> f a > > Implementations are available for, e.g., sequences, sets, and maps. I don't really want some silly list producer. If I want takeWhile.toList, I know where to get it. Similarly, if I want distribute (which I haven't yet), I know where to get it. Some of these proposals also have substantial performance penalties, such as the sort generalization (which also can't be written in an "obviously total" manner, unfortunately). > > >> On Nov 27, 2016 2:10 AM, "Baldur Blöndal" wrote: >> A year ago Edwardk Kmett pointed out some possible generalizations of functions [1], I made a ticket about them that led me here [2]. In addition to the functions mentioned >> >> > maybeToList :: Foldable f => f a -> [a] >> > maybeToList = toList >> >> > catMaybes :: (Foldable f) => f (Maybe a) -> [a] >> > catMaybes :: (Foldable f, Foldable g) => f (g a) -> [a] >> > catMaybes = foldMap toList >> >> > mapMaybes :: (a -> Maybe b) -> (forall f. Foldable f => f a -> [b]) >> > mapMaybes :: Foldable m => (a -> m b) -> (forall f. Foldable f => f a -> [b]) >> > mapMaybes f = foldMap (toList . f) >> >> we also have *many* other functions (I do not propose generalising all these function ((especially when the name stops making sense)), but I will include them) that I will define in the vocabulary of ‘lens’. Some generalise to ‘Foldable’ >> >> > take :: Int -> (forall f a. Foldable f => f a -> [a]) >> > take n = toListOf (taking n folded) >> >> > drop :: Int -> (forall f a. Foldable f => f a -> [a]) >> > drop n = toListOf (dropping n folded) >> >> > takeWhile :: (a -> Bool) -> (forall f. Foldable f => f a -> [a]) >> > takeWhile p = toListOf (takingWhile p folded) >> >> > dropWhile :: (a -> Bool) -> (forall f. Foldable f => f a -> [a]) >> > dropWhile p = toListOf (droppingWhile p folded) >> >> > -- Same as ‘Control.Lens.Indexed.None’ >> > filter :: (a -> Bool) -> (forall f. Foldable f => f a -> [a]) >> > filter p = toListOf (folded.filtered p) >> >> > cycle :: Foldable f => f a -> [a] >> > cycle = toListOf (cycled folded) >> >> > lookup :: Eq k => k -> (forall f. Foldable f => f (k, v) -> Maybe v) >> > lookup = lookupOf folded >> >> > listToMaybe :: Foldable f => f a -> Maybe a >> > listToMaybe = firstOf folded >> >> while others — to ‘Traversable’ >> >> > transpose :: Traversable f => f [b] -> [f b] >> > transpose = transposeOf traverse >> >> > scanl1 :: (a -> a -> a) -> (forall f. Traversable f => f a -> f a) >> > scanl1 = scanl1Of traverse >> >> > scanr1_ :: (a -> a -> a) -> (forall f. Traversable f => f a -> f a) >> > scanr1_ = scanr1Of traverse >> >> More radical suggestions (pay no heed to the hacky ‘partsOf’, assume better implementation [3]) would allow us to sort a ‘data V2 a = V2 a a deriving (…, Traversable)’ if it contains ordered values: >> >> > sort :: (Traversable t, Ord a) => t a -> t a >> > sort = over (partsOf traverse) Data.List.sort >> >> > sortBy :: (a -> a -> Ordering) -> ([a] -> [a]) >> > sortBy = over (partsOf traverse) . Data.List.sortBy >> >> > sortOn :: Ord b => (a -> b) -> ([a] -> [a]) >> > sortOn = over (partsOf traverse) . Data.List.sortOn >> >> > reverse :: Traversable t => t a -> t a >> > reverse = over (partsOf traverse) Data.List.reverse >> >> > -- Based on ‘Control.Lens.??’ >> > flip :: Functor f => f (a -> b) -> a -> f b >> > flip f x = fmap ($ x) f >> >> or >> >> > flip :: (Functor f, Distributive g) => f (g a) -> g (f a) >> > flip = Data.Distributive.distribute >> >> AMP happened some years ago, does this go too far or not far enough? ;) share your thoughts >> >> P.s. I understand those skeptical of the ‘partsOf’ solutions but they do feel magical and uses crop up in odd places, especially in compound structures (I don't have better examples): >> >> > ghci> peopleList = Pair ["Bob", "Eve"] (Just "Alice") >> > ghci> data Product f g a = Pair (f a) (g a) deriving (Show, Functor, Foldable, Traversable) >> > ghci> sort peopleList >> > Pair ["Alice","Bob"] (Just "Eve") >> > ghci> reverse peopleList >> > Pair ["Alice","Eve"] (Just "Bob") >> >> > ghci> peopleMap = fromList [(1,"Bob"),(2,"Eve"),(3,"Alice")] >> > ghci> sort peopleMap >> > fromList [(1,"Alice"),(2,"Bob"),(3,"Eve")] >> > ghci> reverse peopleMap >> > fromList [(1,"Alice"),(2,"Eve"),(3,"Bob")] >> >> [1] https://www.reddit.com/r/haskell/comments/2y2pe5/shouldnt_ftp_propagate_changes_over_the_entire/cp6vpb4/ >> [2] https://ghc.haskell.org/trac/ghc/ticket/12828 >> [3] http://stackoverflow.com/a/33320155/165806 >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries -------------- next part -------------- An HTML attachment was scrubbed... URL: From lanablack at amok.cc Sun Nov 27 17:08:17 2016 From: lanablack at amok.cc (Lana Black) Date: Sun, 27 Nov 2016 17:08:17 +0000 Subject: Many functions can be generalised In-Reply-To: References: Message-ID: <20161127170817.GA15884@glow> On 07:10 Sun 27 Nov , Baldur Blöndal wrote: > > catMaybes :: (Foldable f) => f (Maybe a) -> [a] > > catMaybes :: (Foldable f, Foldable g) => f (g a) -> [a] > > catMaybes = foldMap toList > > > mapMaybes :: (a -> Maybe b) -> (forall f. Foldable f => f a > -> [b]) > > mapMaybes :: Foldable m => (a -> m b) -> (forall f. Foldable f => f a > -> [b]) > > mapMaybes f = foldMap (toList . f) These two as well as 'filter' are generalized in witherable[1]. [1]: https://hackage.haskell.org/package/witherable/ From david.feuer at gmail.com Sun Nov 27 19:10:24 2016 From: david.feuer at gmail.com (David Feuer) Date: Sun, 27 Nov 2016 14:10:24 -0500 Subject: Traversal order newtypes for Data.Tree, and Ord instances Message-ID: Data.Tree.Tree has Foldable and Traversable instances for traversing a tree in preorder. Should we add the derived Ord instance to match? Should we offer newtypes for traversing in post-order and level-order with Eq and Ord instances to match? I've made coercions explicit below, rather than relying on map/coerce rules, to make performance characteristics clearer. deriving instance Ord a => Ord (Tree a) newtype PostOrder a = PostOrder {getPostOrder :: Tree a} deriving (Show, Read, Functor) instance Foldable PostOrder where foldMap f (PostOrder (Node a ts)) = foldMap (foldMap f . PostOrder) ts <> f a instance Traversable PostOrder where traverse f (PostOrder (Node a ts)) = (\ts' a' -> PostOrder (Node a' (coerce ts'))) <$> traverse (traverse f . PostOrder) ts <*> f a instance Eq a => Eq (PostOrder a) where PostOrder a1 ts1 == PostOrder a2 ts2 = (coerce `asTypeOf` map PostOrder) ts1 == coerce ts2 && a1 == a2 instance Ord a => Ord (PostOrder a) where PostOrder a1 ts1 `compare` PostOrder a2 ts2 = ((coerce `asTypeOf` map PostOrder) ts1 `compare` coerce ts2) <> (a1 `compare` a2) newtype LevelOrder a = LevelOrder {getLevelOrder :: Tree a} deriving (Show, Read, Functor) I'm still working out the best ways to perform level-order folds and traversals. One option for Foldable is instance Foldable LevelOrder where foldr c n (LevelOrder (Node a ts)) = a `c` frlof c n ts where frlof :: (a -> b -> b) -> b -> [Tree a] -> b frlof _c n [] = n frlof c n ts = roots where (roots, forest) = uzt c (frlof c n forest) ts uzt :: (a -> b -> b) -> b -> [Tree a] -> (b, [Tree a]) uzt _c n [] = (n, []) uzt c n (Node a fr : ts) = (a `c` n', fr ++ ts') where (n', ts') = uzt c n ts David Feuer From ryan.gl.scott at gmail.com Mon Nov 28 19:36:47 2016 From: ryan.gl.scott at gmail.com (Ryan Scott) Date: Mon, 28 Nov 2016 14:36:47 -0500 Subject: The lazy Show instance for GHC.Generics.U1 is confusing. Message-ID: I don't quite understand your objection (what is the value you're showing?). But the Show U1 instance's laziness is deliberate. We designed all of U1's instances to emulate those of Proxy so that in the future, we could unify the datatypes in GHC.Generics with more standard ecosystem definitions (i.e., replace U1 in favor of Proxy, (:*:) with Product, (:+:) with Sum, etc.) See https://ghc.haskell.org/trac/ghc/ticket/11650 for the discussion on this. Ryan S. From wren at community.haskell.org Mon Nov 28 21:41:08 2016 From: wren at community.haskell.org (wren romano) Date: Mon, 28 Nov 2016 13:41:08 -0800 Subject: Many functions can be generalised In-Reply-To: <20161127170817.GA15884@glow> References: <20161127170817.GA15884@glow> Message-ID: On Sun, Nov 27, 2016 at 9:08 AM, Lana Black wrote: > On 07:10 Sun 27 Nov , Baldur Blöndal wrote: >> > catMaybes :: (Foldable f) => f (Maybe a) -> [a] >> > catMaybes :: (Foldable f, Foldable g) => f (g a) -> [a] >> > catMaybes = foldMap toList >> >> > mapMaybes :: (a -> Maybe b) -> (forall f. Foldable f => f a >> -> [b]) >> > mapMaybes :: Foldable m => (a -> m b) -> (forall f. Foldable f => f a >> -> [b]) >> > mapMaybes f = foldMap (toList . f) > > These two as well as 'filter' are generalized in witherable[1]. > > [1]: https://hackage.haskell.org/package/witherable/ I'm also -1 to the OP. If we want to do these sorts of generalizations, then we should use something like witherable and get that API to where everyone agrees it captures the right concept. Just because we *can* go polymorphic as above doesn't mean those are the proper generalizations. Anything sequential can be made into lists, but that doesn't mean lists are appropriate; lists lose a lot of information. I'd much rather see the above functions as: mapMaybes :: Foo f => (a -> Maybe b) -> f a -> f b catMaybes :: Foo f => f (Maybe a) -> f a Note how the f-structure is retained, rather than being needlessly converted to a list. The above signatures capture the idea that f is "sparse" and can absorb missing values, which is a coherent concept that should have some nice laws we can exploit to clean up our code. Indeed, the Witherable class takes this approach (though it has an unfortunate Traversable dependency I don't think is always appropriate). -- Live well, ~wren From lemming at henning-thielemann.de Tue Nov 29 07:34:02 2016 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Tue, 29 Nov 2016 08:34:02 +0100 (CET) Subject: Many functions can be generalised In-Reply-To: <0EBAE5AD-3E9C-4F78-AB00-9820A613039C@gmail.com> References: <0EBAE5AD-3E9C-4F78-AB00-9820A613039C@gmail.com> Message-ID: On Sun, 27 Nov 2016, amindfv at gmail.com wrote: > I'd also be -1. Function generalization sometimes has a cost in > comprehensability, and there aren't enough benefits to make it worth it > to me. And you lose type inference in more cases. > > maybeToList :: Foldable f => f a -> [a] > > maybeToList = toList Why should we have two names for Foldable.toList, where maybeToList even is no longer special to Maybe? > > take :: Int -> (forall f a. Foldable f => f a -> [a]) > > take n = toListOf (taking n folded) > > > drop :: Int -> (forall f a. Foldable f => f a -> [a]) > > drop n = toListOf (dropping n folded) > > > cycle :: Foldable f => f a -> [a] > > cycle = toListOf (cycled folded) I'd prefer an extension to Monoid, i.e. take :: (??? m) => Int -> m -> m drop :: (??? m) => Int -> m -> m cycle :: (Semigroup m) => m -> m Yet, I do not propose to replace Prelude functions by this generalisations. From baldurpet at gmail.com Wed Nov 30 09:08:27 2016 From: baldurpet at gmail.com (=?UTF-8?Q?Baldur_Bl=C3=B6ndal?=) Date: Wed, 30 Nov 2016 09:08:27 +0000 Subject: Many functions can be generalised In-Reply-To: References: Message-ID: (I meant FTP, not AMP) Fine points, the proposal wasn't a smashing hit but the response has been jolly good. What about functions that aren't expected to preserve structure like ‘lookup’ and (new) suggestions > lookup :: Eq a => k -> Foldable f => f (k, v) -> Maybe v > lookup = lookupOf folded > elemIndex :: Eq a => a -> Foldable f => f a -> Maybe Int > elemIndex = elemIndexOf folded > elemIndices :: Eq a => a -> Foldable f => f a -> Maybe Int > elemIndices = elemIndicesOf folded > findIndex :: (a -> Bool) -> Foldable f => f a -> Maybe Int > findIndex = findIndexOf folded > findIndices :: (a -> Bool) -> Foldable f => f a -> [Int] > findIndices = findIndicesOf folded and the few that do fit that pattern such as ‘scanl1’, ‘scanr1’, possibly ‘transpose’ as well. P.s. At least I did not propose ↓ yet :) > shuffleM :: (Foldable f, MonadRandom m) => f a -> m (f a) > class ... => Sort f where > sort :: Ord a => f a -> f a > sort = over (partsOf traverse) Data.List.sort > default > sort :: Ord a => Traversable f => f a -> f a 2016-11-27 7:53 GMT+00:00 David Feuer : > I disagree with many of these. For example, I think of takeWhile as having > a type shaped like > > takeWhile :: (a -> Bool) -> f a -> f a > > Implementations are available for, e.g., sequences, sets, and maps. I > don't really want some silly list producer. If I want takeWhile.toList, I > know where to get it. Similarly, if I want distribute (which I haven't > yet), I know where to get it. Some of these proposals also have substantial > performance penalties, such as the sort generalization (which also can't be > written in an "obviously total" manner, unfortunately). > > On Nov 27, 2016 2:10 AM, "Baldur Blöndal" wrote: > >> A year ago Edwardk Kmett pointed out some possible generalizations of >> functions [1], I made a ticket about them that led me here [2]. In addition >> to the functions mentioned >> >> > maybeToList :: Foldable f => f a -> [a] >> > maybeToList = toList >> >> > catMaybes :: (Foldable f) => f (Maybe a) -> [a] >> > catMaybes :: (Foldable f, Foldable g) => f (g a) -> [a] >> > catMaybes = foldMap toList >> >> > mapMaybes :: (a -> Maybe b) -> (forall f. Foldable f => f >> a -> [b]) >> > mapMaybes :: Foldable m => (a -> m b) -> (forall f. Foldable f => f >> a -> [b]) >> > mapMaybes f = foldMap (toList . f) >> >> we also have *many* other functions (I do not propose generalising all >> these function ((especially when the name stops making sense)), but I will >> include them) that I will define in the vocabulary of ‘lens’. Some >> generalise to ‘Foldable’ >> >> > take :: Int -> (forall f a. Foldable f => f a -> [a]) >> > take n = toListOf (taking n folded) >> >> > drop :: Int -> (forall f a. Foldable f => f a -> [a]) >> > drop n = toListOf (dropping n folded) >> >> > takeWhile :: (a -> Bool) -> (forall f. Foldable f => f a -> [a]) >> > takeWhile p = toListOf (takingWhile p folded) >> >> > dropWhile :: (a -> Bool) -> (forall f. Foldable f => f a -> [a]) >> > dropWhile p = toListOf (droppingWhile p folded) >> >> > -- Same as ‘Control.Lens.Indexed.None’ >> > filter :: (a -> Bool) -> (forall f. Foldable f => f a -> [a]) >> > filter p = toListOf (folded.filtered p) >> >> > cycle :: Foldable f => f a -> [a] >> > cycle = toListOf (cycled folded) >> >> > lookup :: Eq k => k -> (forall f. Foldable f => f (k, v) -> Maybe v) >> > lookup = lookupOf folded >> >> > listToMaybe :: Foldable f => f a -> Maybe a >> > listToMaybe = firstOf folded >> >> while others — to ‘Traversable’ >> >> > transpose :: Traversable f => f [b] -> [f b] >> > transpose = transposeOf traverse >> >> > scanl1 :: (a -> a -> a) -> (forall f. Traversable f => f a -> f a) >> > scanl1 = scanl1Of traverse >> >> > scanr1_ :: (a -> a -> a) -> (forall f. Traversable f => f a -> f a) >> > scanr1_ = scanr1Of traverse >> >> More radical suggestions (pay no heed to the hacky ‘partsOf’, assume >> better implementation [3]) would allow us to sort a ‘data V2 a = V2 a a >> deriving (…, Traversable)’ if it contains ordered values: >> >> > sort :: (Traversable t, Ord a) => t a -> t a >> > sort = over (partsOf traverse) Data.List.sort >> >> > sortBy :: (a -> a -> Ordering) -> ([a] -> [a]) >> > sortBy = over (partsOf traverse) . Data.List.sortBy >> >> > sortOn :: Ord b => (a -> b) -> ([a] -> [a]) >> > sortOn = over (partsOf traverse) . Data.List.sortOn >> >> > reverse :: Traversable t => t a -> t a >> > reverse = over (partsOf traverse) Data.List.reverse >> >> > -- Based on ‘Control.Lens.??’ >> > flip :: Functor f => f (a -> b) -> a -> f b >> > flip f x = fmap ($ x) f >> >> or >> >> > flip :: (Functor f, Distributive g) => f (g a) -> g (f a) >> > flip = Data.Distributive.distribute >> >> AMP happened some years ago, does this go too far or not far enough? ;) >> share your thoughts >> >> P.s. I understand those skeptical of the ‘partsOf’ solutions but they do >> feel magical and uses crop up in odd places, especially in compound >> structures (I don't have better examples): >> >> > ghci> peopleList = Pair ["Bob", "Eve"] (Just "Alice") >> > ghci> data Product f g a = Pair (f a) (g a) deriving (Show, Functor, >> Foldable, Traversable) >> > ghci> sort peopleList >> > Pair ["Alice","Bob"] (Just "Eve") >> > ghci> reverse peopleList >> > Pair ["Alice","Eve"] (Just "Bob") >> >> > ghci> peopleMap = fromList [(1,"Bob"),(2,"Eve"),(3,"Alice")] >> > ghci> sort peopleMap >> > fromList [(1,"Alice"),(2,"Bob"),(3,"Eve")] >> > ghci> reverse peopleMap >> > fromList [(1,"Alice"),(2,"Eve"),(3,"Bob")] >> >> [1] https://www.reddit.com/r/haskell/comments/2y2pe5/shouldnt_ >> ftp_propagate_changes_over_the_entire/cp6vpb4/ >> [2] https://ghc.haskell.org/trac/ghc/ticket/12828 >> [3] http://stackoverflow.com/a/33320155/165806 >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From baldurpet at gmail.com Wed Nov 30 10:30:48 2016 From: baldurpet at gmail.com (=?UTF-8?Q?Baldur_Bl=C3=B6ndal?=) Date: Wed, 30 Nov 2016 10:30:48 +0000 Subject: Many functions can be generalised In-Reply-To: References: Message-ID: Meant > elemIndices :: Eq a => a -> Foldable f => f a -> [Int] -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Wed Nov 30 12:02:18 2016 From: david.feuer at gmail.com (David Feuer) Date: Wed, 30 Nov 2016 07:02:18 -0500 Subject: Many functions can be generalised In-Reply-To: References: Message-ID: `lookup`, and the rest of the association list nonsense, are the wrong shape to generalize altogether. Please don't try. I wish they weren't in there at all. Some other things you mention might work; I'll have to look more closely. On Nov 30, 2016 4:08 AM, "Baldur Blöndal" wrote: > (I meant FTP, not AMP) > > Fine points, the proposal wasn't a smashing hit but the response has been > jolly good. > > What about functions that aren't expected to preserve structure like > ‘lookup’ and (new) suggestions > > > lookup :: Eq a => k -> Foldable f => f (k, v) -> Maybe v > > lookup = lookupOf folded > > > elemIndex :: Eq a => a -> Foldable f => f a -> Maybe Int > > elemIndex = elemIndexOf folded > > > elemIndices :: Eq a => a -> Foldable f => f a -> Maybe Int > > elemIndices = elemIndicesOf folded > > > findIndex :: (a -> Bool) -> Foldable f => f a -> Maybe Int > > findIndex = findIndexOf folded > > > findIndices :: (a -> Bool) -> Foldable f => f a -> [Int] > > findIndices = findIndicesOf folded > > and the few that do fit that pattern such as ‘scanl1’, ‘scanr1’, possibly > ‘transpose’ as well. > > P.s. At least I did not propose ↓ yet :) > > > shuffleM :: (Foldable f, MonadRandom m) => f a -> m (f a) > > > class ... => Sort f where > > sort :: Ord a => f a -> f a > > sort = over (partsOf traverse) Data.List.sort > > default > > sort :: Ord a => Traversable f => f a -> f a > > 2016-11-27 7:53 GMT+00:00 David Feuer : > >> I disagree with many of these. For example, I think of takeWhile as >> having a type shaped like >> >> takeWhile :: (a -> Bool) -> f a -> f a >> >> Implementations are available for, e.g., sequences, sets, and maps. I >> don't really want some silly list producer. If I want takeWhile.toList, I >> know where to get it. Similarly, if I want distribute (which I haven't >> yet), I know where to get it. Some of these proposals also have substantial >> performance penalties, such as the sort generalization (which also can't be >> written in an "obviously total" manner, unfortunately). >> >> On Nov 27, 2016 2:10 AM, "Baldur Blöndal" wrote: >> >>> A year ago Edwardk Kmett pointed out some possible generalizations of >>> functions [1], I made a ticket about them that led me here [2]. In addition >>> to the functions mentioned >>> >>> > maybeToList :: Foldable f => f a -> [a] >>> > maybeToList = toList >>> >>> > catMaybes :: (Foldable f) => f (Maybe a) -> [a] >>> > catMaybes :: (Foldable f, Foldable g) => f (g a) -> [a] >>> > catMaybes = foldMap toList >>> >>> > mapMaybes :: (a -> Maybe b) -> (forall f. Foldable f => >>> f a -> [b]) >>> > mapMaybes :: Foldable m => (a -> m b) -> (forall f. Foldable f => >>> f a -> [b]) >>> > mapMaybes f = foldMap (toList . f) >>> >>> we also have *many* other functions (I do not propose generalising all >>> these function ((especially when the name stops making sense)), but I will >>> include them) that I will define in the vocabulary of ‘lens’. Some >>> generalise to ‘Foldable’ >>> >>> > take :: Int -> (forall f a. Foldable f => f a -> [a]) >>> > take n = toListOf (taking n folded) >>> >>> > drop :: Int -> (forall f a. Foldable f => f a -> [a]) >>> > drop n = toListOf (dropping n folded) >>> >>> > takeWhile :: (a -> Bool) -> (forall f. Foldable f => f a -> [a]) >>> > takeWhile p = toListOf (takingWhile p folded) >>> >>> > dropWhile :: (a -> Bool) -> (forall f. Foldable f => f a -> [a]) >>> > dropWhile p = toListOf (droppingWhile p folded) >>> >>> > -- Same as ‘Control.Lens.Indexed.None’ >>> > filter :: (a -> Bool) -> (forall f. Foldable f => f a -> [a]) >>> > filter p = toListOf (folded.filtered p) >>> >>> > cycle :: Foldable f => f a -> [a] >>> > cycle = toListOf (cycled folded) >>> >>> > lookup :: Eq k => k -> (forall f. Foldable f => f (k, v) -> Maybe v) >>> > lookup = lookupOf folded >>> >>> > listToMaybe :: Foldable f => f a -> Maybe a >>> > listToMaybe = firstOf folded >>> >>> while others — to ‘Traversable’ >>> >>> > transpose :: Traversable f => f [b] -> [f b] >>> > transpose = transposeOf traverse >>> >>> > scanl1 :: (a -> a -> a) -> (forall f. Traversable f => f a -> f a) >>> > scanl1 = scanl1Of traverse >>> >>> > scanr1_ :: (a -> a -> a) -> (forall f. Traversable f => f a -> f a) >>> > scanr1_ = scanr1Of traverse >>> >>> More radical suggestions (pay no heed to the hacky ‘partsOf’, assume >>> better implementation [3]) would allow us to sort a ‘data V2 a = V2 a a >>> deriving (…, Traversable)’ if it contains ordered values: >>> >>> > sort :: (Traversable t, Ord a) => t a -> t a >>> > sort = over (partsOf traverse) Data.List.sort >>> >>> > sortBy :: (a -> a -> Ordering) -> ([a] -> [a]) >>> > sortBy = over (partsOf traverse) . Data.List.sortBy >>> >>> > sortOn :: Ord b => (a -> b) -> ([a] -> [a]) >>> > sortOn = over (partsOf traverse) . Data.List.sortOn >>> >>> > reverse :: Traversable t => t a -> t a >>> > reverse = over (partsOf traverse) Data.List.reverse >>> >>> > -- Based on ‘Control.Lens.??’ >>> > flip :: Functor f => f (a -> b) -> a -> f b >>> > flip f x = fmap ($ x) f >>> >>> or >>> >>> > flip :: (Functor f, Distributive g) => f (g a) -> g (f a) >>> > flip = Data.Distributive.distribute >>> >>> AMP happened some years ago, does this go too far or not far enough? ;) >>> share your thoughts >>> >>> P.s. I understand those skeptical of the ‘partsOf’ solutions but they do >>> feel magical and uses crop up in odd places, especially in compound >>> structures (I don't have better examples): >>> >>> > ghci> peopleList = Pair ["Bob", "Eve"] (Just "Alice") >>> > ghci> data Product f g a = Pair (f a) (g a) deriving (Show, Functor, >>> Foldable, Traversable) >>> > ghci> sort peopleList >>> > Pair ["Alice","Bob"] (Just "Eve") >>> > ghci> reverse peopleList >>> > Pair ["Alice","Eve"] (Just "Bob") >>> >>> > ghci> peopleMap = fromList [(1,"Bob"),(2,"Eve"),(3,"Alice")] >>> > ghci> sort peopleMap >>> > fromList [(1,"Alice"),(2,"Bob"),(3,"Eve")] >>> > ghci> reverse peopleMap >>> > fromList [(1,"Alice"),(2,"Eve"),(3,"Bob")] >>> >>> [1] https://www.reddit.com/r/haskell/comments/2y2pe5/shouldnt_ft >>> p_propagate_changes_over_the_entire/cp6vpb4/ >>> [2] https://ghc.haskell.org/trac/ghc/ticket/12828 >>> [3] http://stackoverflow.com/a/33320155/165806 >>> >>> _______________________________________________ >>> Libraries mailing list >>> Libraries at haskell.org >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >>> >>> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From lanablack at amok.cc Wed Nov 30 23:25:15 2016 From: lanablack at amok.cc (Lana Black) Date: Wed, 30 Nov 2016 23:25:15 +0000 Subject: Many functions can be generalised In-Reply-To: References: Message-ID: <20161130232515.GB15884@glow> On 09:08 Wed 30 Nov , Baldur Blöndal wrote: > P.s. At least I did not propose ↓ yet :) > > > shuffleM :: (Foldable f, MonadRandom m) => f a -> m (f a) This would be an utter nonsense, given that many if not most foldables either don't have an order like Set or must have very specific order like different kinds of trees and therefore cannot be shuffled. From david.feuer at gmail.com Wed Nov 30 23:25:56 2016 From: david.feuer at gmail.com (David Feuer) Date: Wed, 30 Nov 2016 18:25:56 -0500 Subject: Many functions can be generalised In-Reply-To: <20161130232515.GB15884@glow> References: <20161130232515.GB15884@glow> Message-ID: This was probably supposed to be a Traversable constraint. I still suspect it would be unwise, because there may be data structures that can be shuffled more efficiently than this type would allow. On Nov 30, 2016 6:22 PM, "Lana Black" wrote: > On 09:08 Wed 30 Nov , Baldur Blöndal wrote: > > P.s. At least I did not propose ↓ yet :) > > > > > shuffleM :: (Foldable f, MonadRandom m) => f a -> m (f a) > > This would be an utter nonsense, given that many if not most foldables > either don't have an order like Set or must have very specific order > like different kinds of trees and therefore cannot be shuffled. > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: