From carter.schonwald at gmail.com Mon Feb 3 21:34:39 2020 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Mon, 3 Feb 2020 16:34:39 -0500 Subject: Break `abs` into two aspects In-Reply-To: References: <2AD564B3-A853-4749-A48B-844DA40983DA@gmail.com> Message-ID: Andrew: could you explain the algebra notation you were using for short hand? I think I followed, but for people the libraries list might be their first exposure to advanced / graduate abstract algebra (which winds up being simpler than most folks expect ;) ) On Fri, Jan 31, 2020 at 4:36 PM Carter Schonwald wrote: > that actually sounds pretty sane. I think! > > On Fri, Jan 31, 2020 at 3:38 PM Andrew Lelechenko < > andrew.lelechenko at gmail.com> wrote: > >> On Tue, 28 Jan 2020, Dannyu NDos wrote: >> >> > Second, I suggest to move `abs` and `signum` from `Num` to `Floating` >> >> I can fully relate your frustration with `abs` and `signum` (and numeric >> type classes in Haskell altogether). But IMO breaking both in `Num` and in >> `Floating` at once is not a promising way to make things proper. >> >> I would rather follow the beaten track of Applicative Monad and Semigroup >> Monoid proposals and - as a first step - introduce a superclass (probably, >> borrowing the design from `semirings` package): >> >> class Semiring a where >> zero :: a >> plus :: a -> a -> a >> one :: a >> times :: a -> a -> a >> fromNatural :: Natural -> a >> class Semiring a => Num a where ... >> >> Tangible benefits in `base` include: >> a) instance Semiring Bool, >> b) a total instance Semiring Natural (in contrast to a partial instance >> Num Natural), >> c) instance Num a => Semiring (Complex a) (in contrast to instance >> RealFloat a => Num (Complex a)), >> d) newtypes Sum and Product would require only Semiring constraint >> instead of Num. >> >> Best regards, >> Andrew >> >> >> _______________________________________________ >> 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 andreas.abel at ifi.lmu.de Tue Feb 4 08:21:32 2020 From: andreas.abel at ifi.lmu.de (Andreas Abel) Date: Tue, 4 Feb 2020 09:21:32 +0100 Subject: Break `abs` into two aspects In-Reply-To: References: <2AD564B3-A853-4749-A48B-844DA40983DA@gmail.com> Message-ID: > class Semiring a where > zero :: a > plus :: a -> a -> a > one :: a > times :: a -> a -> a > fromNatural :: Natural -> a I think `fromNatural` should not be part of the `Semiring` class, but we could have an extension (NaturalSemiring) that adds this method. In the Agda code base, we have, for lack of a standard, rolled our own semiring class, https://github.com/agda/agda/blob/master/src/full/Agda/Utils/SemiRing.hs and we use it for several finite semirings, e.g., https://github.com/agda/agda/blob/64c0c2e813a84f91b3accd7c56efaa53712bc3f5/src/full/Agda/TypeChecking/Positivity/Occurrence.hs#L127-L155 Cheers, Andreas On 2020-02-03 22:34, Carter Schonwald wrote: > Andrew: could you explain the algebra notation you were using for short > hand?  I think I followed, but for people the libraries list might be > their first exposure to advanced / graduate abstract algebra (which > winds up being simpler than most folks expect ;) ) > > On Fri, Jan 31, 2020 at 4:36 PM Carter Schonwald > > wrote: > > that actually sounds pretty sane. I think! > > On Fri, Jan 31, 2020 at 3:38 PM Andrew Lelechenko > > > wrote: > > On Tue, 28 Jan 2020, Dannyu NDos wrote: > > > Second, I suggest to move `abs` and `signum` from `Num` to > `Floating` > > I can fully relate your frustration with `abs` and `signum` (and > numeric type classes in Haskell altogether). But IMO breaking > both in `Num` and in `Floating` at once is not a promising way > to make things proper. > > I would rather follow the beaten track of Applicative Monad and > Semigroup Monoid proposals and - as a first step - introduce a > superclass (probably, borrowing the design from `semirings` > package): > > class Semiring a where >   zero  :: a >   plus  :: a -> a -> a >   one   :: a >   times :: a -> a -> a >   fromNatural :: Natural -> a > class Semiring a => Num a where ... > > Tangible benefits in `base` include: > a) instance Semiring Bool, > b) a total instance Semiring Natural (in contrast to a partial > instance Num Natural), > c) instance Num a => Semiring (Complex a) (in contrast to > instance RealFloat a => Num (Complex a)), > d) newtypes Sum and Product would require only Semiring > constraint instead of Num. > > Best regards, > Andrew > > > _______________________________________________ > 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 zemyla at gmail.com Tue Feb 4 12:42:22 2020 From: zemyla at gmail.com (Zemyla) Date: Tue, 4 Feb 2020 06:42:22 -0600 Subject: Break `abs` into two aspects In-Reply-To: References: <2AD564B3-A853-4749-A48B-844DA40983DA@gmail.com> Message-ID: There is a homomorphism from the Naturals to any Semiring, which obeys: fromNatural 0 = zero fromNatural 1 = one fromNatural (m + n) = fromNatural m `plus` fromNatural n fromNatural (m * n) = fromNatural m `times` fromNatural n The simplest implementation is this, but it's nowhere near the most efficient: fromNatural :: Semiring a => Natural -> a fromNatural 0 = zero fromNatural n = one `plus` fromNatural (n - 1) One which takes O(log n) time instead of O(n) would go like this: fromNatural :: Semiring a => Natural -> a fromNatural = go 0 zero one go i s m n | i `seq` s `seq` m `seq` n `seq` False = undefined go _ s _ 0 = s go i s m n | testBit n i = go (i + 1) (plus s m) (plus m m) (clearBit n i) | otherwise = go (i + 1) s (plus m m) n On Tue, Feb 4, 2020, 02:21 Andreas Abel wrote: > > class Semiring a where > > zero :: a > > plus :: a -> a -> a > > one :: a > > times :: a -> a -> a > > fromNatural :: Natural -> a > > I think `fromNatural` should not be part of the `Semiring` class, but we > could have an extension (NaturalSemiring) that adds this method. > > In the Agda code base, we have, for lack of a standard, rolled our own > semiring class, > > > https://github.com/agda/agda/blob/master/src/full/Agda/Utils/SemiRing.hs > > and we use it for several finite semirings, e.g., > > > > https://github.com/agda/agda/blob/64c0c2e813a84f91b3accd7c56efaa53712bc3f5/src/full/Agda/TypeChecking/Positivity/Occurrence.hs#L127-L155 > > Cheers, > Andreas > > On 2020-02-03 22:34, Carter Schonwald wrote: > > Andrew: could you explain the algebra notation you were using for short > > hand? I think I followed, but for people the libraries list might be > > their first exposure to advanced / graduate abstract algebra (which > > winds up being simpler than most folks expect ;) ) > > > > On Fri, Jan 31, 2020 at 4:36 PM Carter Schonwald > > > wrote: > > > > that actually sounds pretty sane. I think! > > > > On Fri, Jan 31, 2020 at 3:38 PM Andrew Lelechenko > > > > > wrote: > > > > On Tue, 28 Jan 2020, Dannyu NDos wrote: > > > > > Second, I suggest to move `abs` and `signum` from `Num` to > > `Floating` > > > > I can fully relate your frustration with `abs` and `signum` (and > > numeric type classes in Haskell altogether). But IMO breaking > > both in `Num` and in `Floating` at once is not a promising way > > to make things proper. > > > > I would rather follow the beaten track of Applicative Monad and > > Semigroup Monoid proposals and - as a first step - introduce a > > superclass (probably, borrowing the design from `semirings` > > package): > > > > class Semiring a where > > zero :: a > > plus :: a -> a -> a > > one :: a > > times :: a -> a -> a > > fromNatural :: Natural -> a > > class Semiring a => Num a where ... > > > > Tangible benefits in `base` include: > > a) instance Semiring Bool, > > b) a total instance Semiring Natural (in contrast to a partial > > instance Num Natural), > > c) instance Num a => Semiring (Complex a) (in contrast to > > instance RealFloat a => Num (Complex a)), > > d) newtypes Sum and Product would require only Semiring > > constraint instead of Num. > > > > Best regards, > > Andrew > > > > > > _______________________________________________ > > 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 andreas.abel at ifi.lmu.de Tue Feb 4 15:20:24 2020 From: andreas.abel at ifi.lmu.de (Andreas Abel) Date: Tue, 4 Feb 2020 16:20:24 +0100 Subject: Break `abs` into two aspects In-Reply-To: References: <2AD564B3-A853-4749-A48B-844DA40983DA@gmail.com> Message-ID: <0c092823-4fd6-fba3-cc93-dcb4d128fef5@ifi.lmu.de> > There is a homomorphism from the Naturals to any Semiring Sure, but there are many finite semirings where I would not care about such a homomorphism, thus, why force me to define it? > fromNatural 0 = zero > fromNatural 1 = one > fromNatural (m + n) = fromNatural m `plus` fromNatural n > fromNatural (m * n) = fromNatural m `times` fromNatural n This might not be surjective, and also not very interesting. For instance consider the semiring Set Bool zero = Set.empty one = Set.singleton True plus = Set.union times s t = { x == y | x <- s, y <- t } This semiring models variances (covariant = {True}, contravariant = {False}, constant = {}, dontknow = {True,False}). times is for function composition and plus combination of information. The fromNatural targets only the zero/one-fragment since plus is idempotent. I conjecture there is not a single surjective semiring-hom from Nat to Set Bool. Thus, a function fromNatural is totally uninteresting for the general case of semirings. On 2020-02-04 13:42, Zemyla wrote: > There is a homomorphism from the Naturals to any Semiring, which obeys: > > fromNatural 0 = zero > fromNatural 1 = one > fromNatural (m + n) = fromNatural m `plus` fromNatural n > fromNatural (m * n) = fromNatural m `times` fromNatural n > > The simplest implementation is this, but it's nowhere near the most > efficient: > > fromNatural :: Semiring a => Natural -> a > fromNatural 0 = zero > fromNatural n = one `plus` fromNatural (n - 1) > > One which takes O(log n) time instead of O(n) would go like this: > > fromNatural :: Semiring a => Natural -> a > fromNatural = go 0 zero one >   go i s m n | i `seq` s `seq` m `seq` n `seq` False = undefined >   go _ s _ 0 =  s >   go i s m n >     | testBit n i = go (i + 1) (plus s m) (plus m m) (clearBit n i) >     | otherwise = go (i + 1) s (plus m m) n > > On Tue, Feb 4, 2020, 02:21 Andreas Abel > wrote: > >  >         class Semiring a where >  >            zero  :: a >  >            plus  :: a -> a -> a >  >            one   :: a >  >            times :: a -> a -> a >  >            fromNatural :: Natural -> a > > I think `fromNatural` should not be part of the `Semiring` class, > but we > could have an extension (NaturalSemiring) that adds this method. > > In the Agda code base, we have, for lack of a standard, rolled our own > semiring class, > > https://github.com/agda/agda/blob/master/src/full/Agda/Utils/SemiRing.hs > > and we use it for several finite semirings, e.g., > > > https://github.com/agda/agda/blob/64c0c2e813a84f91b3accd7c56efaa53712bc3f5/src/full/Agda/TypeChecking/Positivity/Occurrence.hs#L127-L155 > > Cheers, > Andreas > > On 2020-02-03 22:34, Carter Schonwald wrote: > > Andrew: could you explain the algebra notation you were using for > short > > hand?  I think I followed, but for people the libraries list > might be > > their first exposure to advanced / graduate abstract algebra (which > > winds up being simpler than most folks expect ;) ) > > > > On Fri, Jan 31, 2020 at 4:36 PM Carter Schonwald > > > >> wrote: > > > >     that actually sounds pretty sane. I think! > > > >     On Fri, Jan 31, 2020 at 3:38 PM Andrew Lelechenko > >      > >> > >     wrote: > > > >         On Tue, 28 Jan 2020, Dannyu NDos wrote: > > > >          > Second, I suggest to move `abs` and `signum` from `Num` to > >         `Floating` > > > >         I can fully relate your frustration with `abs` and > `signum` (and > >         numeric type classes in Haskell altogether). But IMO breaking > >         both in `Num` and in `Floating` at once is not a > promising way > >         to make things proper. > > > >         I would rather follow the beaten track of Applicative > Monad and > >         Semigroup Monoid proposals and - as a first step - > introduce a > >         superclass (probably, borrowing the design from `semirings` > >         package): > > > >         class Semiring a where > >            zero  :: a > >            plus  :: a -> a -> a > >            one   :: a > >            times :: a -> a -> a > >            fromNatural :: Natural -> a > >         class Semiring a => Num a where ... > > > >         Tangible benefits in `base` include: > >         a) instance Semiring Bool, > >         b) a total instance Semiring Natural (in contrast to a > partial > >         instance Num Natural), > >         c) instance Num a => Semiring (Complex a) (in contrast to > >         instance RealFloat a => Num (Complex a)), > >         d) newtypes Sum and Product would require only Semiring > >         constraint instead of Num. > > > >         Best regards, > >         Andrew > > > > > >         _______________________________________________ > >         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 > From zemyla at gmail.com Tue Feb 4 16:32:43 2020 From: zemyla at gmail.com (Zemyla) Date: Tue, 4 Feb 2020 10:32:43 -0600 Subject: Break `abs` into two aspects In-Reply-To: <0c092823-4fd6-fba3-cc93-dcb4d128fef5@ifi.lmu.de> References: <2AD564B3-A853-4749-A48B-844DA40983DA@gmail.com> <0c092823-4fd6-fba3-cc93-dcb4d128fef5@ifi.lmu.de> Message-ID: It really doesn't matter if it's not "interesting" or not surjective for some Semirings. It should be included, because: (a) Even for semirings where it is "interesting", it's not surjective (for instance, Rational or Double) (b) It's a method with a default definition, so you don't have to expend any mental effort on it (c) A lot of instances have uninteresting methods: for instance, (*>) and (<*) for Applicative ((->) e) are const id and const respectively. Haskell adds methods to classes when they're always possible and sometimes useful/interesting/faster, rather than when they're always interesting. (d) It's useful for Semiring-generic methods and instances. (e) It can achieve an asymptotic speedup on some instances. Like, if you have Semiring a => Semiring (f a) for some type f, then you can have fromNatural n = pure (fromNatural n) instead of doing the whole O(log n) song and dance with the default definition. Also, your example admits a simple definition: fromNatural n = if n == 0 then S.empty else S.singleton True (f) "zero" and "one" can be defined in terms of fromNatural, for programmers who only need to define that: zero = fromNatural 0 one = fromNatural 1 This leads to the MINIMAL pragma on Semiring being {-# MINIMAL plus, times, (zero, one | fromNatural) #-} (g) If it's not included in the class, but in some subclass (NaturalSemiring, you proposed), but it's possible from the class, then people will just define and use the O(log n) version instead of requiring the subclass, leading to wasted effort and duplicated code. On Tue, Feb 4, 2020, 09:20 Andreas Abel wrote: > > There is a homomorphism from the Naturals to any Semiring > > Sure, but there are many finite semirings where I would not care about > such a homomorphism, thus, why force me to define it? > > > fromNatural 0 = zero > > fromNatural 1 = one > > fromNatural (m + n) = fromNatural m `plus` fromNatural n > > fromNatural (m * n) = fromNatural m `times` fromNatural n > > This might not be surjective, and also not very interesting. For > instance consider the semiring > > Set Bool > zero = Set.empty > one = Set.singleton True > plus = Set.union > times s t = { x == y | x <- s, y <- t } > > This semiring models variances (covariant = {True}, contravariant = > {False}, constant = {}, dontknow = {True,False}). times is for function > composition and plus combination of information. > > The fromNatural targets only the zero/one-fragment since plus is > idempotent. I conjecture there is not a single surjective semiring-hom > from Nat to Set Bool. Thus, a function fromNatural is totally > uninteresting for the general case of semirings. > > On 2020-02-04 13:42, Zemyla wrote: > > There is a homomorphism from the Naturals to any Semiring, which obeys: > > > > fromNatural 0 = zero > > fromNatural 1 = one > > fromNatural (m + n) = fromNatural m `plus` fromNatural n > > fromNatural (m * n) = fromNatural m `times` fromNatural n > > > > The simplest implementation is this, but it's nowhere near the most > > efficient: > > > > fromNatural :: Semiring a => Natural -> a > > fromNatural 0 = zero > > fromNatural n = one `plus` fromNatural (n - 1) > > > > One which takes O(log n) time instead of O(n) would go like this: > > > > fromNatural :: Semiring a => Natural -> a > > fromNatural = go 0 zero one > > go i s m n | i `seq` s `seq` m `seq` n `seq` False = undefined > > go _ s _ 0 = s > > go i s m n > > | testBit n i = go (i + 1) (plus s m) (plus m m) (clearBit n i) > > | otherwise = go (i + 1) s (plus m m) n > > > > On Tue, Feb 4, 2020, 02:21 Andreas Abel > > wrote: > > > > > class Semiring a where > > > zero :: a > > > plus :: a -> a -> a > > > one :: a > > > times :: a -> a -> a > > > fromNatural :: Natural -> a > > > > I think `fromNatural` should not be part of the `Semiring` class, > > but we > > could have an extension (NaturalSemiring) that adds this method. > > > > In the Agda code base, we have, for lack of a standard, rolled our > own > > semiring class, > > > > > https://github.com/agda/agda/blob/master/src/full/Agda/Utils/SemiRing.hs > > > > and we use it for several finite semirings, e.g., > > > > > > > https://github.com/agda/agda/blob/64c0c2e813a84f91b3accd7c56efaa53712bc3f5/src/full/Agda/TypeChecking/Positivity/Occurrence.hs#L127-L155 > > > > Cheers, > > Andreas > > > > On 2020-02-03 22:34, Carter Schonwald wrote: > > > Andrew: could you explain the algebra notation you were using for > > short > > > hand? I think I followed, but for people the libraries list > > might be > > > their first exposure to advanced / graduate abstract algebra > (which > > > winds up being simpler than most folks expect ;) ) > > > > > > On Fri, Jan 31, 2020 at 4:36 PM Carter Schonwald > > > > > > >> wrote: > > > > > > that actually sounds pretty sane. I think! > > > > > > On Fri, Jan 31, 2020 at 3:38 PM Andrew Lelechenko > > > > > > > >> > > > wrote: > > > > > > On Tue, 28 Jan 2020, Dannyu NDos wrote: > > > > > > > Second, I suggest to move `abs` and `signum` from > `Num` to > > > `Floating` > > > > > > I can fully relate your frustration with `abs` and > > `signum` (and > > > numeric type classes in Haskell altogether). But IMO > breaking > > > both in `Num` and in `Floating` at once is not a > > promising way > > > to make things proper. > > > > > > I would rather follow the beaten track of Applicative > > Monad and > > > Semigroup Monoid proposals and - as a first step - > > introduce a > > > superclass (probably, borrowing the design from > `semirings` > > > package): > > > > > > class Semiring a where > > > zero :: a > > > plus :: a -> a -> a > > > one :: a > > > times :: a -> a -> a > > > fromNatural :: Natural -> a > > > class Semiring a => Num a where ... > > > > > > Tangible benefits in `base` include: > > > a) instance Semiring Bool, > > > b) a total instance Semiring Natural (in contrast to a > > partial > > > instance Num Natural), > > > c) instance Num a => Semiring (Complex a) (in contrast to > > > instance RealFloat a => Num (Complex a)), > > > d) newtypes Sum and Product would require only Semiring > > > constraint instead of Num. > > > > > > Best regards, > > > Andrew > > > > > > > > > _______________________________________________ > > > 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 carter.schonwald at gmail.com Tue Feb 4 17:09:21 2020 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Tue, 4 Feb 2020 12:09:21 -0500 Subject: Break `abs` into two aspects In-Reply-To: References: <2AD564B3-A853-4749-A48B-844DA40983DA@gmail.com> <0c092823-4fd6-fba3-cc93-dcb4d128fef5@ifi.lmu.de> Message-ID: well said! On Tue, Feb 4, 2020 at 11:32 AM Zemyla wrote: > It really doesn't matter if it's not "interesting" or not surjective for > some Semirings. It should be included, because: > > (a) Even for semirings where it is "interesting", it's not surjective (for > instance, Rational or Double) > (b) It's a method with a default definition, so you don't have to expend > any mental effort on it > (c) A lot of instances have uninteresting methods: for instance, (*>) and > (<*) for Applicative ((->) e) are const id and const respectively. Haskell > adds methods to classes when they're always possible and sometimes > useful/interesting/faster, rather than when they're always interesting. > (d) It's useful for Semiring-generic methods and instances. > (e) It can achieve an asymptotic speedup on some instances. Like, if you > have Semiring a => Semiring (f a) for some type f, then you can have > fromNatural n = pure (fromNatural n) instead of doing the whole O(log n) > song and dance with the default definition. Also, your example admits a > simple definition: > fromNatural n = if n == 0 then S.empty else S.singleton True > (f) "zero" and "one" can be defined in terms of fromNatural, for > programmers who only need to define that: > zero = fromNatural 0 > one = fromNatural 1 > This leads to the MINIMAL pragma on Semiring being {-# MINIMAL plus, > times, (zero, one | fromNatural) #-} > (g) If it's not included in the class, but in some subclass > (NaturalSemiring, you proposed), but it's possible from the class, then > people will just define and use the O(log n) version instead of requiring > the subclass, leading to wasted effort and duplicated code. > > On Tue, Feb 4, 2020, 09:20 Andreas Abel wrote: > >> > There is a homomorphism from the Naturals to any Semiring >> >> Sure, but there are many finite semirings where I would not care about >> such a homomorphism, thus, why force me to define it? >> >> > fromNatural 0 = zero >> > fromNatural 1 = one >> > fromNatural (m + n) = fromNatural m `plus` fromNatural n >> > fromNatural (m * n) = fromNatural m `times` fromNatural n >> >> This might not be surjective, and also not very interesting. For >> instance consider the semiring >> >> Set Bool >> zero = Set.empty >> one = Set.singleton True >> plus = Set.union >> times s t = { x == y | x <- s, y <- t } >> >> This semiring models variances (covariant = {True}, contravariant = >> {False}, constant = {}, dontknow = {True,False}). times is for function >> composition and plus combination of information. >> >> The fromNatural targets only the zero/one-fragment since plus is >> idempotent. I conjecture there is not a single surjective semiring-hom >> from Nat to Set Bool. Thus, a function fromNatural is totally >> uninteresting for the general case of semirings. >> >> On 2020-02-04 13:42, Zemyla wrote: >> > There is a homomorphism from the Naturals to any Semiring, which obeys: >> > >> > fromNatural 0 = zero >> > fromNatural 1 = one >> > fromNatural (m + n) = fromNatural m `plus` fromNatural n >> > fromNatural (m * n) = fromNatural m `times` fromNatural n >> > >> > The simplest implementation is this, but it's nowhere near the most >> > efficient: >> > >> > fromNatural :: Semiring a => Natural -> a >> > fromNatural 0 = zero >> > fromNatural n = one `plus` fromNatural (n - 1) >> > >> > One which takes O(log n) time instead of O(n) would go like this: >> > >> > fromNatural :: Semiring a => Natural -> a >> > fromNatural = go 0 zero one >> > go i s m n | i `seq` s `seq` m `seq` n `seq` False = undefined >> > go _ s _ 0 = s >> > go i s m n >> > | testBit n i = go (i + 1) (plus s m) (plus m m) (clearBit n i) >> > | otherwise = go (i + 1) s (plus m m) n >> > >> > On Tue, Feb 4, 2020, 02:21 Andreas Abel > > > wrote: >> > >> > > class Semiring a where >> > > zero :: a >> > > plus :: a -> a -> a >> > > one :: a >> > > times :: a -> a -> a >> > > fromNatural :: Natural -> a >> > >> > I think `fromNatural` should not be part of the `Semiring` class, >> > but we >> > could have an extension (NaturalSemiring) that adds this method. >> > >> > In the Agda code base, we have, for lack of a standard, rolled our >> own >> > semiring class, >> > >> > >> https://github.com/agda/agda/blob/master/src/full/Agda/Utils/SemiRing.hs >> > >> > and we use it for several finite semirings, e.g., >> > >> > >> > >> https://github.com/agda/agda/blob/64c0c2e813a84f91b3accd7c56efaa53712bc3f5/src/full/Agda/TypeChecking/Positivity/Occurrence.hs#L127-L155 >> > >> > Cheers, >> > Andreas >> > >> > On 2020-02-03 22:34, Carter Schonwald wrote: >> > > Andrew: could you explain the algebra notation you were using for >> > short >> > > hand? I think I followed, but for people the libraries list >> > might be >> > > their first exposure to advanced / graduate abstract algebra >> (which >> > > winds up being simpler than most folks expect ;) ) >> > > >> > > On Fri, Jan 31, 2020 at 4:36 PM Carter Schonwald >> > > >> > > > >> wrote: >> > > >> > > that actually sounds pretty sane. I think! >> > > >> > > On Fri, Jan 31, 2020 at 3:38 PM Andrew Lelechenko >> > > > > >> > > > >> >> > > wrote: >> > > >> > > On Tue, 28 Jan 2020, Dannyu NDos wrote: >> > > >> > > > Second, I suggest to move `abs` and `signum` from >> `Num` to >> > > `Floating` >> > > >> > > I can fully relate your frustration with `abs` and >> > `signum` (and >> > > numeric type classes in Haskell altogether). But IMO >> breaking >> > > both in `Num` and in `Floating` at once is not a >> > promising way >> > > to make things proper. >> > > >> > > I would rather follow the beaten track of Applicative >> > Monad and >> > > Semigroup Monoid proposals and - as a first step - >> > introduce a >> > > superclass (probably, borrowing the design from >> `semirings` >> > > package): >> > > >> > > class Semiring a where >> > > zero :: a >> > > plus :: a -> a -> a >> > > one :: a >> > > times :: a -> a -> a >> > > fromNatural :: Natural -> a >> > > class Semiring a => Num a where ... >> > > >> > > Tangible benefits in `base` include: >> > > a) instance Semiring Bool, >> > > b) a total instance Semiring Natural (in contrast to a >> > partial >> > > instance Num Natural), >> > > c) instance Num a => Semiring (Complex a) (in contrast to >> > > instance RealFloat a => Num (Complex a)), >> > > d) newtypes Sum and Product would require only Semiring >> > > constraint instead of Num. >> > > >> > > Best regards, >> > > Andrew >> > > >> > > >> > > _______________________________________________ >> > > 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 carter.schonwald at gmail.com Wed Feb 5 18:08:39 2020 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Wed, 5 Feb 2020 13:08:39 -0500 Subject: Remove MonadFail (ST s) instance In-Reply-To: References: <7b128d60-35a0-317d-b96c-3a93064f6dc1@iki.fi> Message-ID: do we have a tracking ticket on gitlab for this? On Tue, Nov 26, 2019 at 4:28 AM chessai . wrote: > +1 on removal > > On Tue, Nov 26, 2019, 4:04 AM Matthew Farkas-Dyck > wrote: > >> +1 from me, this instance is insane >> _______________________________________________ >> 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 carter.schonwald at gmail.com Wed Feb 5 18:21:49 2020 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Wed, 5 Feb 2020 13:21:49 -0500 Subject: Remove MonadFail (ST s) instance In-Reply-To: References: <7b128d60-35a0-317d-b96c-3a93064f6dc1@iki.fi> Message-ID: This does seem like a reasonable request, Though of course it’d be really cool to evaluate what code may be incidentally using the monad fail instance by accident atm! (is there any way we could do that?) On Sun, Nov 24, 2019 at 12:35 PM Henning Thielemann < lemming at henning-thielemann.de> wrote: > > On Sun, 24 Nov 2019, Dan Burton wrote: > > > We're talking about an instance in `base`, so if there's no other way, > it could at least be a flag akin to > > -Wmissing-monadfail-instances that gets included in -Wcompat. > > But relatedly: should there be a way to deprecate instances? I would say > yes. > > Sounds like another application of instance warnings that we already > talked about: > https://gitlab.haskell.org/ghc/ghc/issues/11796 > _______________________________________________ > 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 andreas.abel at ifi.lmu.de Wed Feb 5 18:34:09 2020 From: andreas.abel at ifi.lmu.de (Andreas Abel) Date: Wed, 5 Feb 2020 19:34:09 +0100 Subject: Break `abs` into two aspects In-Reply-To: References: <2AD564B3-A853-4749-A48B-844DA40983DA@gmail.com> <0c092823-4fd6-fba3-cc93-dcb4d128fef5@ifi.lmu.de> Message-ID: <12a99812-6ad3-4861-0ea2-419a699d67b1@ifi.lmu.de> Well, I see your arguments, but cannot help the feeling that you are reasoning from a specific instance family of semirings, namely numerical ones (N, Z, Q, ...). For idempotent semirings (e.g. the example I gave), repetitively adding one gets you nowhere. (Cf. also lattices, many of which are semirings.) I'd be convinced if Natural was something like the free semiring, but this is certainly not the case. Semirings are really diverse, I don't think the Semiring class should be hijacked for a particular flavor of semirings. We do not have any such pretext for Semigroup or Monoid either. Enjoy the diversity at https://en.wikipedia.org/wiki/Semiring On 2020-02-04 17:32, Zemyla wrote: > It really doesn't matter if it's not "interesting" or not surjective for > some Semirings. It should be included, because: > > (a) Even for semirings where it is "interesting", it's not surjective > (for instance, Rational or Double) > (b) It's a method with a default definition, so you don't have to expend > any mental effort on it > (c) A lot of instances have uninteresting methods: for instance, (*>) > and (<*) for Applicative ((->) e) are const id and const respectively. > Haskell adds methods to classes when they're always possible and > sometimes useful/interesting/faster, rather than when they're always > interesting. > (d) It's useful for Semiring-generic methods and instances. > (e) It can achieve an asymptotic speedup on some instances. Like, if you > have Semiring a => Semiring (f a) for some type f, then you can have > fromNatural n = pure (fromNatural n) instead of doing the whole O(log n) > song and dance with the default definition. Also, your example admits a > simple definition: >   fromNatural n = if n == 0 then S.empty else S.singleton True > (f) "zero" and "one" can be defined in terms of fromNatural, for > programmers who only need to define that: >   zero = fromNatural 0 >   one = fromNatural 1 > This leads to the MINIMAL pragma on Semiring being {-# MINIMAL plus, > times, (zero, one | fromNatural) #-} > (g) If it's not included in the class, but in some subclass > (NaturalSemiring, you proposed), but it's possible from the class, then > people will just define and use the O(log n) version instead of > requiring the subclass, leading to wasted effort and duplicated code. > > On Tue, Feb 4, 2020, 09:20 Andreas Abel > wrote: > >  > There is a homomorphism from the Naturals to any Semiring > > Sure, but there are many finite semirings where I would not care about > such a homomorphism, thus, why force me to define it? > >  > fromNatural 0 = zero >  > fromNatural 1 = one >  > fromNatural (m + n) = fromNatural m `plus` fromNatural n >  > fromNatural (m * n) = fromNatural m `times` fromNatural n > > This might not be surjective, and also not very interesting.  For > instance consider the semiring > >    Set Bool >    zero  = Set.empty >    one   = Set.singleton True >    plus  = Set.union >    times s t = { x == y | x <- s, y <- t } > > This semiring models variances (covariant = {True}, contravariant = > {False}, constant = {}, dontknow = {True,False}).  times is for > function > composition and plus combination of information. > > The fromNatural targets only the zero/one-fragment since plus is > idempotent.  I conjecture there is not a single surjective semiring-hom > from Nat to Set Bool.  Thus, a function fromNatural is totally > uninteresting for the general case of semirings. > > On 2020-02-04 13:42, Zemyla wrote: > > There is a homomorphism from the Naturals to any Semiring, which > obeys: > > > > fromNatural 0 = zero > > fromNatural 1 = one > > fromNatural (m + n) = fromNatural m `plus` fromNatural n > > fromNatural (m * n) = fromNatural m `times` fromNatural n > > > > The simplest implementation is this, but it's nowhere near the most > > efficient: > > > > fromNatural :: Semiring a => Natural -> a > > fromNatural 0 = zero > > fromNatural n = one `plus` fromNatural (n - 1) > > > > One which takes O(log n) time instead of O(n) would go like this: > > > > fromNatural :: Semiring a => Natural -> a > > fromNatural = go 0 zero one > >    go i s m n | i `seq` s `seq` m `seq` n `seq` False = undefined > >    go _ s _ 0 =  s > >    go i s m n > >      | testBit n i = go (i + 1) (plus s m) (plus m m) (clearBit n i) > >      | otherwise = go (i + 1) s (plus m m) n > > > > On Tue, Feb 4, 2020, 02:21 Andreas Abel > > >> wrote: > > > >       >         class Semiring a where > >       >            zero  :: a > >       >            plus  :: a -> a -> a > >       >            one   :: a > >       >            times :: a -> a -> a > >       >            fromNatural :: Natural -> a > > > >     I think `fromNatural` should not be part of the `Semiring` class, > >     but we > >     could have an extension (NaturalSemiring) that adds this method. > > > >     In the Agda code base, we have, for lack of a standard, > rolled our own > >     semiring class, > > > > > https://github.com/agda/agda/blob/master/src/full/Agda/Utils/SemiRing.hs > > > >     and we use it for several finite semirings, e.g., > > > > > > > https://github.com/agda/agda/blob/64c0c2e813a84f91b3accd7c56efaa53712bc3f5/src/full/Agda/TypeChecking/Positivity/Occurrence.hs#L127-L155 > > > >     Cheers, > >     Andreas > > > >     On 2020-02-03 22:34, Carter Schonwald wrote: > >      > Andrew: could you explain the algebra notation you were > using for > >     short > >      > hand?  I think I followed, but for people the libraries list > >     might be > >      > their first exposure to advanced / graduate abstract > algebra (which > >      > winds up being simpler than most folks expect ;) ) > >      > > >      > On Fri, Jan 31, 2020 at 4:36 PM Carter Schonwald > >      > > > > >      > >      >>> wrote: > >      > > >      >     that actually sounds pretty sane. I think! > >      > > >      >     On Fri, Jan 31, 2020 at 3:38 PM Andrew Lelechenko > >      >      > >      > > >      > >      >>> > >      >     wrote: > >      > > >      >         On Tue, 28 Jan 2020, Dannyu NDos wrote: > >      > > >      >          > Second, I suggest to move `abs` and `signum` > from `Num` to > >      >         `Floating` > >      > > >      >         I can fully relate your frustration with `abs` and > >     `signum` (and > >      >         numeric type classes in Haskell altogether). But > IMO breaking > >      >         both in `Num` and in `Floating` at once is not a > >     promising way > >      >         to make things proper. > >      > > >      >         I would rather follow the beaten track of Applicative > >     Monad and > >      >         Semigroup Monoid proposals and - as a first step - > >     introduce a > >      >         superclass (probably, borrowing the design from > `semirings` > >      >         package): > >      > > >      >         class Semiring a where > >      >            zero  :: a > >      >            plus  :: a -> a -> a > >      >            one   :: a > >      >            times :: a -> a -> a > >      >            fromNatural :: Natural -> a > >      >         class Semiring a => Num a where ... > >      > > >      >         Tangible benefits in `base` include: > >      >         a) instance Semiring Bool, > >      >         b) a total instance Semiring Natural (in contrast to a > >     partial > >      >         instance Num Natural), > >      >         c) instance Num a => Semiring (Complex a) (in > contrast to > >      >         instance RealFloat a => Num (Complex a)), > >      >         d) newtypes Sum and Product would require only > Semiring > >      >         constraint instead of Num. > >      > > >      >         Best regards, > >      >         Andrew > >      > > >      > > >      >         _______________________________________________ > >      >         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 > > > From carter.schonwald at gmail.com Wed Feb 5 18:50:54 2020 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Wed, 5 Feb 2020 13:50:54 -0500 Subject: Break `abs` into two aspects In-Reply-To: <12a99812-6ad3-4861-0ea2-419a699d67b1@ifi.lmu.de> References: <2AD564B3-A853-4749-A48B-844DA40983DA@gmail.com> <0c092823-4fd6-fba3-cc93-dcb4d128fef5@ifi.lmu.de> <12a99812-6ad3-4861-0ea2-419a699d67b1@ifi.lmu.de> Message-ID: ooo, thats a good point about lattices/partial orders! (we like those here too, but sometimes forget :) ) On Wed, Feb 5, 2020 at 1:34 PM Andreas Abel wrote: > Well, I see your arguments, but cannot help the feeling that you are > reasoning from a specific instance family of semirings, namely numerical > ones (N, Z, Q, ...). > > For idempotent semirings (e.g. the example I gave), repetitively adding > one gets you nowhere. (Cf. also lattices, many of which are semirings.) > > I'd be convinced if Natural was something like the free semiring, but > this is certainly not the case. > > Semirings are really diverse, I don't think the Semiring class should be > hijacked for a particular flavor of semirings. We do not have any such > pretext for Semigroup or Monoid either. > > Enjoy the diversity at https://en.wikipedia.org/wiki/Semiring > > On 2020-02-04 17:32, Zemyla wrote: > > It really doesn't matter if it's not "interesting" or not surjective for > > some Semirings. It should be included, because: > > > > (a) Even for semirings where it is "interesting", it's not surjective > > (for instance, Rational or Double) > > (b) It's a method with a default definition, so you don't have to expend > > any mental effort on it > > (c) A lot of instances have uninteresting methods: for instance, (*>) > > and (<*) for Applicative ((->) e) are const id and const respectively. > > Haskell adds methods to classes when they're always possible and > > sometimes useful/interesting/faster, rather than when they're always > > interesting. > > (d) It's useful for Semiring-generic methods and instances. > > (e) It can achieve an asymptotic speedup on some instances. Like, if you > > have Semiring a => Semiring (f a) for some type f, then you can have > > fromNatural n = pure (fromNatural n) instead of doing the whole O(log n) > > song and dance with the default definition. Also, your example admits a > > simple definition: > > fromNatural n = if n == 0 then S.empty else S.singleton True > > (f) "zero" and "one" can be defined in terms of fromNatural, for > > programmers who only need to define that: > > zero = fromNatural 0 > > one = fromNatural 1 > > This leads to the MINIMAL pragma on Semiring being {-# MINIMAL plus, > > times, (zero, one | fromNatural) #-} > > (g) If it's not included in the class, but in some subclass > > (NaturalSemiring, you proposed), but it's possible from the class, then > > people will just define and use the O(log n) version instead of > > requiring the subclass, leading to wasted effort and duplicated code. > > > > On Tue, Feb 4, 2020, 09:20 Andreas Abel > > wrote: > > > > > There is a homomorphism from the Naturals to any Semiring > > > > Sure, but there are many finite semirings where I would not care > about > > such a homomorphism, thus, why force me to define it? > > > > > fromNatural 0 = zero > > > fromNatural 1 = one > > > fromNatural (m + n) = fromNatural m `plus` fromNatural n > > > fromNatural (m * n) = fromNatural m `times` fromNatural n > > > > This might not be surjective, and also not very interesting. For > > instance consider the semiring > > > > Set Bool > > zero = Set.empty > > one = Set.singleton True > > plus = Set.union > > times s t = { x == y | x <- s, y <- t } > > > > This semiring models variances (covariant = {True}, contravariant = > > {False}, constant = {}, dontknow = {True,False}). times is for > > function > > composition and plus combination of information. > > > > The fromNatural targets only the zero/one-fragment since plus is > > idempotent. I conjecture there is not a single surjective > semiring-hom > > from Nat to Set Bool. Thus, a function fromNatural is totally > > uninteresting for the general case of semirings. > > > > On 2020-02-04 13:42, Zemyla wrote: > > > There is a homomorphism from the Naturals to any Semiring, which > > obeys: > > > > > > fromNatural 0 = zero > > > fromNatural 1 = one > > > fromNatural (m + n) = fromNatural m `plus` fromNatural n > > > fromNatural (m * n) = fromNatural m `times` fromNatural n > > > > > > The simplest implementation is this, but it's nowhere near the > most > > > efficient: > > > > > > fromNatural :: Semiring a => Natural -> a > > > fromNatural 0 = zero > > > fromNatural n = one `plus` fromNatural (n - 1) > > > > > > One which takes O(log n) time instead of O(n) would go like this: > > > > > > fromNatural :: Semiring a => Natural -> a > > > fromNatural = go 0 zero one > > > go i s m n | i `seq` s `seq` m `seq` n `seq` False = undefined > > > go _ s _ 0 = s > > > go i s m n > > > | testBit n i = go (i + 1) (plus s m) (plus m m) (clearBit n > i) > > > | otherwise = go (i + 1) s (plus m m) n > > > > > > On Tue, Feb 4, 2020, 02:21 Andreas Abel > > > > > >> wrote: > > > > > > > class Semiring a where > > > > zero :: a > > > > plus :: a -> a -> a > > > > one :: a > > > > times :: a -> a -> a > > > > fromNatural :: Natural -> a > > > > > > I think `fromNatural` should not be part of the `Semiring` > class, > > > but we > > > could have an extension (NaturalSemiring) that adds this > method. > > > > > > In the Agda code base, we have, for lack of a standard, > > rolled our own > > > semiring class, > > > > > > > > > https://github.com/agda/agda/blob/master/src/full/Agda/Utils/SemiRing.hs > > > > > > and we use it for several finite semirings, e.g., > > > > > > > > > > > > https://github.com/agda/agda/blob/64c0c2e813a84f91b3accd7c56efaa53712bc3f5/src/full/Agda/TypeChecking/Positivity/Occurrence.hs#L127-L155 > > > > > > Cheers, > > > Andreas > > > > > > On 2020-02-03 22:34, Carter Schonwald wrote: > > > > Andrew: could you explain the algebra notation you were > > using for > > > short > > > > hand? I think I followed, but for people the libraries > list > > > might be > > > > their first exposure to advanced / graduate abstract > > algebra (which > > > > winds up being simpler than most folks expect ;) ) > > > > > > > > On Fri, Jan 31, 2020 at 4:36 PM Carter Schonwald > > > > > > > carter.schonwald at gmail.com>> > > > > > > > > >>> wrote: > > > > > > > > that actually sounds pretty sane. I think! > > > > > > > > On Fri, Jan 31, 2020 at 3:38 PM Andrew Lelechenko > > > > > > > > > > > > > > > > > > >>> > > > > wrote: > > > > > > > > On Tue, 28 Jan 2020, Dannyu NDos wrote: > > > > > > > > > Second, I suggest to move `abs` and `signum` > > from `Num` to > > > > `Floating` > > > > > > > > I can fully relate your frustration with `abs` and > > > `signum` (and > > > > numeric type classes in Haskell altogether). But > > IMO breaking > > > > both in `Num` and in `Floating` at once is not a > > > promising way > > > > to make things proper. > > > > > > > > I would rather follow the beaten track of > Applicative > > > Monad and > > > > Semigroup Monoid proposals and - as a first step - > > > introduce a > > > > superclass (probably, borrowing the design from > > `semirings` > > > > package): > > > > > > > > class Semiring a where > > > > zero :: a > > > > plus :: a -> a -> a > > > > one :: a > > > > times :: a -> a -> a > > > > fromNatural :: Natural -> a > > > > class Semiring a => Num a where ... > > > > > > > > Tangible benefits in `base` include: > > > > a) instance Semiring Bool, > > > > b) a total instance Semiring Natural (in contrast > to a > > > partial > > > > instance Num Natural), > > > > c) instance Num a => Semiring (Complex a) (in > > contrast to > > > > instance RealFloat a => Num (Complex a)), > > > > d) newtypes Sum and Product would require only > > Semiring > > > > constraint instead of Num. > > > > > > > > Best regards, > > > > Andrew > > > > > > > > > > > > _______________________________________________ > > > > 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 zemyla at gmail.com Wed Feb 5 19:00:30 2020 From: zemyla at gmail.com (Zemyla) Date: Wed, 5 Feb 2020 13:00:30 -0600 Subject: Break `abs` into two aspects In-Reply-To: References: <2AD564B3-A853-4749-A48B-844DA40983DA@gmail.com> <0c092823-4fd6-fba3-cc93-dcb4d128fef5@ifi.lmu.de> <12a99812-6ad3-4861-0ea2-419a699d67b1@ifi.lmu.de> Message-ID: If your semiring is idempotent, then you can simply have fromNatural = idempotentFromNatural where idempotentFromNatural :: Semiring a => Natural -> a idempotentFromNatural n = if n == 0 then zero else one It's like stimes in Semigroup. The default implementation is almost always sensible, and sometimes it can have more meaning (like how the Sum monoid allows negative values as the repeat argument in stimes). And again, it's an operation that can be defined by default on all Semirings, and can be vastly faster than the default on some. That, in my opinion, justifies its inclusion. If you don't feel it's meaningful for your Semiring, just let it be defined by default. But it's definitely useful for numeric and derived ones. On Wed, Feb 5, 2020, 12:51 Carter Schonwald wrote: > ooo, thats a good point about lattices/partial orders! (we like those here > too, but sometimes forget :) ) > > On Wed, Feb 5, 2020 at 1:34 PM Andreas Abel > wrote: > >> Well, I see your arguments, but cannot help the feeling that you are >> reasoning from a specific instance family of semirings, namely numerical >> ones (N, Z, Q, ...). >> >> For idempotent semirings (e.g. the example I gave), repetitively adding >> one gets you nowhere. (Cf. also lattices, many of which are semirings.) >> >> I'd be convinced if Natural was something like the free semiring, but >> this is certainly not the case. >> >> Semirings are really diverse, I don't think the Semiring class should be >> hijacked for a particular flavor of semirings. We do not have any such >> pretext for Semigroup or Monoid either. >> >> Enjoy the diversity at https://en.wikipedia.org/wiki/Semiring >> >> On 2020-02-04 17:32, Zemyla wrote: >> > It really doesn't matter if it's not "interesting" or not surjective >> for >> > some Semirings. It should be included, because: >> > >> > (a) Even for semirings where it is "interesting", it's not surjective >> > (for instance, Rational or Double) >> > (b) It's a method with a default definition, so you don't have to >> expend >> > any mental effort on it >> > (c) A lot of instances have uninteresting methods: for instance, (*>) >> > and (<*) for Applicative ((->) e) are const id and const respectively. >> > Haskell adds methods to classes when they're always possible and >> > sometimes useful/interesting/faster, rather than when they're always >> > interesting. >> > (d) It's useful for Semiring-generic methods and instances. >> > (e) It can achieve an asymptotic speedup on some instances. Like, if >> you >> > have Semiring a => Semiring (f a) for some type f, then you can have >> > fromNatural n = pure (fromNatural n) instead of doing the whole O(log >> n) >> > song and dance with the default definition. Also, your example admits a >> > simple definition: >> > fromNatural n = if n == 0 then S.empty else S.singleton True >> > (f) "zero" and "one" can be defined in terms of fromNatural, for >> > programmers who only need to define that: >> > zero = fromNatural 0 >> > one = fromNatural 1 >> > This leads to the MINIMAL pragma on Semiring being {-# MINIMAL plus, >> > times, (zero, one | fromNatural) #-} >> > (g) If it's not included in the class, but in some subclass >> > (NaturalSemiring, you proposed), but it's possible from the class, then >> > people will just define and use the O(log n) version instead of >> > requiring the subclass, leading to wasted effort and duplicated code. >> > >> > On Tue, Feb 4, 2020, 09:20 Andreas Abel > > > wrote: >> > >> > > There is a homomorphism from the Naturals to any Semiring >> > >> > Sure, but there are many finite semirings where I would not care >> about >> > such a homomorphism, thus, why force me to define it? >> > >> > > fromNatural 0 = zero >> > > fromNatural 1 = one >> > > fromNatural (m + n) = fromNatural m `plus` fromNatural n >> > > fromNatural (m * n) = fromNatural m `times` fromNatural n >> > >> > This might not be surjective, and also not very interesting. For >> > instance consider the semiring >> > >> > Set Bool >> > zero = Set.empty >> > one = Set.singleton True >> > plus = Set.union >> > times s t = { x == y | x <- s, y <- t } >> > >> > This semiring models variances (covariant = {True}, contravariant = >> > {False}, constant = {}, dontknow = {True,False}). times is for >> > function >> > composition and plus combination of information. >> > >> > The fromNatural targets only the zero/one-fragment since plus is >> > idempotent. I conjecture there is not a single surjective >> semiring-hom >> > from Nat to Set Bool. Thus, a function fromNatural is totally >> > uninteresting for the general case of semirings. >> > >> > On 2020-02-04 13:42, Zemyla wrote: >> > > There is a homomorphism from the Naturals to any Semiring, which >> > obeys: >> > > >> > > fromNatural 0 = zero >> > > fromNatural 1 = one >> > > fromNatural (m + n) = fromNatural m `plus` fromNatural n >> > > fromNatural (m * n) = fromNatural m `times` fromNatural n >> > > >> > > The simplest implementation is this, but it's nowhere near the >> most >> > > efficient: >> > > >> > > fromNatural :: Semiring a => Natural -> a >> > > fromNatural 0 = zero >> > > fromNatural n = one `plus` fromNatural (n - 1) >> > > >> > > One which takes O(log n) time instead of O(n) would go like this: >> > > >> > > fromNatural :: Semiring a => Natural -> a >> > > fromNatural = go 0 zero one >> > > go i s m n | i `seq` s `seq` m `seq` n `seq` False = undefined >> > > go _ s _ 0 = s >> > > go i s m n >> > > | testBit n i = go (i + 1) (plus s m) (plus m m) (clearBit >> n i) >> > > | otherwise = go (i + 1) s (plus m m) n >> > > >> > > On Tue, Feb 4, 2020, 02:21 Andreas Abel > > >> > > > > >> wrote: >> > > >> > > > class Semiring a where >> > > > zero :: a >> > > > plus :: a -> a -> a >> > > > one :: a >> > > > times :: a -> a -> a >> > > > fromNatural :: Natural -> a >> > > >> > > I think `fromNatural` should not be part of the `Semiring` >> class, >> > > but we >> > > could have an extension (NaturalSemiring) that adds this >> method. >> > > >> > > In the Agda code base, we have, for lack of a standard, >> > rolled our own >> > > semiring class, >> > > >> > > >> > >> https://github.com/agda/agda/blob/master/src/full/Agda/Utils/SemiRing.hs >> > > >> > > and we use it for several finite semirings, e.g., >> > > >> > > >> > > >> > >> https://github.com/agda/agda/blob/64c0c2e813a84f91b3accd7c56efaa53712bc3f5/src/full/Agda/TypeChecking/Positivity/Occurrence.hs#L127-L155 >> > > >> > > Cheers, >> > > Andreas >> > > >> > > On 2020-02-03 22:34, Carter Schonwald wrote: >> > > > Andrew: could you explain the algebra notation you were >> > using for >> > > short >> > > > hand? I think I followed, but for people the libraries >> list >> > > might be >> > > > their first exposure to advanced / graduate abstract >> > algebra (which >> > > > winds up being simpler than most folks expect ;) ) >> > > > >> > > > On Fri, Jan 31, 2020 at 4:36 PM Carter Schonwald >> > > > > > >> > > carter.schonwald at gmail.com>> >> > > > > >> > > > > >>> wrote: >> > > > >> > > > that actually sounds pretty sane. I think! >> > > > >> > > > On Fri, Jan 31, 2020 at 3:38 PM Andrew Lelechenko >> > > > > > >> > > > > > >> > > > > >> > > > > >>> >> > > > wrote: >> > > > >> > > > On Tue, 28 Jan 2020, Dannyu NDos wrote: >> > > > >> > > > > Second, I suggest to move `abs` and `signum` >> > from `Num` to >> > > > `Floating` >> > > > >> > > > I can fully relate your frustration with `abs` and >> > > `signum` (and >> > > > numeric type classes in Haskell altogether). But >> > IMO breaking >> > > > both in `Num` and in `Floating` at once is not a >> > > promising way >> > > > to make things proper. >> > > > >> > > > I would rather follow the beaten track of >> Applicative >> > > Monad and >> > > > Semigroup Monoid proposals and - as a first step - >> > > introduce a >> > > > superclass (probably, borrowing the design from >> > `semirings` >> > > > package): >> > > > >> > > > class Semiring a where >> > > > zero :: a >> > > > plus :: a -> a -> a >> > > > one :: a >> > > > times :: a -> a -> a >> > > > fromNatural :: Natural -> a >> > > > class Semiring a => Num a where ... >> > > > >> > > > Tangible benefits in `base` include: >> > > > a) instance Semiring Bool, >> > > > b) a total instance Semiring Natural (in contrast >> to a >> > > partial >> > > > instance Num Natural), >> > > > c) instance Num a => Semiring (Complex a) (in >> > contrast to >> > > > instance RealFloat a => Num (Complex a)), >> > > > d) newtypes Sum and Product would require only >> > Semiring >> > > > constraint instead of Num. >> > > > >> > > > Best regards, >> > > > Andrew >> > > > >> > > > >> > > > _______________________________________________ >> > > > 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 carter.schonwald at gmail.com Wed Feb 5 19:24:19 2020 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Wed, 5 Feb 2020 14:24:19 -0500 Subject: Break `abs` into two aspects In-Reply-To: References: <2AD564B3-A853-4749-A48B-844DA40983DA@gmail.com> <0c092823-4fd6-fba3-cc93-dcb4d128fef5@ifi.lmu.de> <12a99812-6ad3-4861-0ea2-419a699d67b1@ifi.lmu.de> Message-ID: ok, so would you make the case that "fromNatural" always can have a definition thats sound/satisfactory, even fro those ones that Andreas Abel is saying we're ignoring? On Wed, Feb 5, 2020 at 2:00 PM Zemyla wrote: > If your semiring is idempotent, then you can simply have > > fromNatural = idempotentFromNatural > > where > > idempotentFromNatural :: Semiring a => Natural -> a > idempotentFromNatural n = if n == 0 then zero else one > > It's like stimes in Semigroup. The default implementation is almost always > sensible, and sometimes it can have more meaning (like how the Sum monoid > allows negative values as the repeat argument in stimes). > > And again, it's an operation that can be defined by default on all > Semirings, and can be vastly faster than the default on some. That, in my > opinion, justifies its inclusion. If you don't feel it's meaningful for > your Semiring, just let it be defined by default. But it's definitely > useful for numeric and derived ones. > > On Wed, Feb 5, 2020, 12:51 Carter Schonwald > wrote: > >> ooo, thats a good point about lattices/partial orders! (we like those >> here too, but sometimes forget :) ) >> >> On Wed, Feb 5, 2020 at 1:34 PM Andreas Abel >> wrote: >> >>> Well, I see your arguments, but cannot help the feeling that you are >>> reasoning from a specific instance family of semirings, namely numerical >>> ones (N, Z, Q, ...). >>> >>> For idempotent semirings (e.g. the example I gave), repetitively adding >>> one gets you nowhere. (Cf. also lattices, many of which are semirings.) >>> >>> I'd be convinced if Natural was something like the free semiring, but >>> this is certainly not the case. >>> >>> Semirings are really diverse, I don't think the Semiring class should be >>> hijacked for a particular flavor of semirings. We do not have any such >>> pretext for Semigroup or Monoid either. >>> >>> Enjoy the diversity at https://en.wikipedia.org/wiki/Semiring >>> >>> On 2020-02-04 17:32, Zemyla wrote: >>> > It really doesn't matter if it's not "interesting" or not surjective >>> for >>> > some Semirings. It should be included, because: >>> > >>> > (a) Even for semirings where it is "interesting", it's not surjective >>> > (for instance, Rational or Double) >>> > (b) It's a method with a default definition, so you don't have to >>> expend >>> > any mental effort on it >>> > (c) A lot of instances have uninteresting methods: for instance, (*>) >>> > and (<*) for Applicative ((->) e) are const id and const respectively. >>> > Haskell adds methods to classes when they're always possible and >>> > sometimes useful/interesting/faster, rather than when they're always >>> > interesting. >>> > (d) It's useful for Semiring-generic methods and instances. >>> > (e) It can achieve an asymptotic speedup on some instances. Like, if >>> you >>> > have Semiring a => Semiring (f a) for some type f, then you can have >>> > fromNatural n = pure (fromNatural n) instead of doing the whole O(log >>> n) >>> > song and dance with the default definition. Also, your example admits >>> a >>> > simple definition: >>> > fromNatural n = if n == 0 then S.empty else S.singleton True >>> > (f) "zero" and "one" can be defined in terms of fromNatural, for >>> > programmers who only need to define that: >>> > zero = fromNatural 0 >>> > one = fromNatural 1 >>> > This leads to the MINIMAL pragma on Semiring being {-# MINIMAL plus, >>> > times, (zero, one | fromNatural) #-} >>> > (g) If it's not included in the class, but in some subclass >>> > (NaturalSemiring, you proposed), but it's possible from the class, >>> then >>> > people will just define and use the O(log n) version instead of >>> > requiring the subclass, leading to wasted effort and duplicated code. >>> > >>> > On Tue, Feb 4, 2020, 09:20 Andreas Abel >> > > wrote: >>> > >>> > > There is a homomorphism from the Naturals to any Semiring >>> > >>> > Sure, but there are many finite semirings where I would not care >>> about >>> > such a homomorphism, thus, why force me to define it? >>> > >>> > > fromNatural 0 = zero >>> > > fromNatural 1 = one >>> > > fromNatural (m + n) = fromNatural m `plus` fromNatural n >>> > > fromNatural (m * n) = fromNatural m `times` fromNatural n >>> > >>> > This might not be surjective, and also not very interesting. For >>> > instance consider the semiring >>> > >>> > Set Bool >>> > zero = Set.empty >>> > one = Set.singleton True >>> > plus = Set.union >>> > times s t = { x == y | x <- s, y <- t } >>> > >>> > This semiring models variances (covariant = {True}, contravariant = >>> > {False}, constant = {}, dontknow = {True,False}). times is for >>> > function >>> > composition and plus combination of information. >>> > >>> > The fromNatural targets only the zero/one-fragment since plus is >>> > idempotent. I conjecture there is not a single surjective >>> semiring-hom >>> > from Nat to Set Bool. Thus, a function fromNatural is totally >>> > uninteresting for the general case of semirings. >>> > >>> > On 2020-02-04 13:42, Zemyla wrote: >>> > > There is a homomorphism from the Naturals to any Semiring, which >>> > obeys: >>> > > >>> > > fromNatural 0 = zero >>> > > fromNatural 1 = one >>> > > fromNatural (m + n) = fromNatural m `plus` fromNatural n >>> > > fromNatural (m * n) = fromNatural m `times` fromNatural n >>> > > >>> > > The simplest implementation is this, but it's nowhere near the >>> most >>> > > efficient: >>> > > >>> > > fromNatural :: Semiring a => Natural -> a >>> > > fromNatural 0 = zero >>> > > fromNatural n = one `plus` fromNatural (n - 1) >>> > > >>> > > One which takes O(log n) time instead of O(n) would go like >>> this: >>> > > >>> > > fromNatural :: Semiring a => Natural -> a >>> > > fromNatural = go 0 zero one >>> > > go i s m n | i `seq` s `seq` m `seq` n `seq` False = >>> undefined >>> > > go _ s _ 0 = s >>> > > go i s m n >>> > > | testBit n i = go (i + 1) (plus s m) (plus m m) (clearBit >>> n i) >>> > > | otherwise = go (i + 1) s (plus m m) n >>> > > >>> > > On Tue, Feb 4, 2020, 02:21 Andreas Abel < >>> andreas.abel at ifi.lmu.de >>> > >>> > > >> > >> wrote: >>> > > >>> > > > class Semiring a where >>> > > > zero :: a >>> > > > plus :: a -> a -> a >>> > > > one :: a >>> > > > times :: a -> a -> a >>> > > > fromNatural :: Natural -> a >>> > > >>> > > I think `fromNatural` should not be part of the `Semiring` >>> class, >>> > > but we >>> > > could have an extension (NaturalSemiring) that adds this >>> method. >>> > > >>> > > In the Agda code base, we have, for lack of a standard, >>> > rolled our own >>> > > semiring class, >>> > > >>> > > >>> > >>> https://github.com/agda/agda/blob/master/src/full/Agda/Utils/SemiRing.hs >>> > > >>> > > and we use it for several finite semirings, e.g., >>> > > >>> > > >>> > > >>> > >>> https://github.com/agda/agda/blob/64c0c2e813a84f91b3accd7c56efaa53712bc3f5/src/full/Agda/TypeChecking/Positivity/Occurrence.hs#L127-L155 >>> > > >>> > > Cheers, >>> > > Andreas >>> > > >>> > > On 2020-02-03 22:34, Carter Schonwald wrote: >>> > > > Andrew: could you explain the algebra notation you were >>> > using for >>> > > short >>> > > > hand? I think I followed, but for people the libraries >>> list >>> > > might be >>> > > > their first exposure to advanced / graduate abstract >>> > algebra (which >>> > > > winds up being simpler than most folks expect ;) ) >>> > > > >>> > > > On Fri, Jan 31, 2020 at 4:36 PM Carter Schonwald >>> > > > >> > >>> > >> carter.schonwald at gmail.com>> >>> > > >> > >>> > > >> > >>> wrote: >>> > > > >>> > > > that actually sounds pretty sane. I think! >>> > > > >>> > > > On Fri, Jan 31, 2020 at 3:38 PM Andrew Lelechenko >>> > > > >> > >>> > > >> > > >>> > > >> > >>> > > >> > >>> >>> > > > wrote: >>> > > > >>> > > > On Tue, 28 Jan 2020, Dannyu NDos wrote: >>> > > > >>> > > > > Second, I suggest to move `abs` and `signum` >>> > from `Num` to >>> > > > `Floating` >>> > > > >>> > > > I can fully relate your frustration with `abs` >>> and >>> > > `signum` (and >>> > > > numeric type classes in Haskell altogether). But >>> > IMO breaking >>> > > > both in `Num` and in `Floating` at once is not a >>> > > promising way >>> > > > to make things proper. >>> > > > >>> > > > I would rather follow the beaten track of >>> Applicative >>> > > Monad and >>> > > > Semigroup Monoid proposals and - as a first step >>> - >>> > > introduce a >>> > > > superclass (probably, borrowing the design from >>> > `semirings` >>> > > > package): >>> > > > >>> > > > class Semiring a where >>> > > > zero :: a >>> > > > plus :: a -> a -> a >>> > > > one :: a >>> > > > times :: a -> a -> a >>> > > > fromNatural :: Natural -> a >>> > > > class Semiring a => Num a where ... >>> > > > >>> > > > Tangible benefits in `base` include: >>> > > > a) instance Semiring Bool, >>> > > > b) a total instance Semiring Natural (in >>> contrast to a >>> > > partial >>> > > > instance Num Natural), >>> > > > c) instance Num a => Semiring (Complex a) (in >>> > contrast to >>> > > > instance RealFloat a => Num (Complex a)), >>> > > > d) newtypes Sum and Product would require only >>> > Semiring >>> > > > constraint instead of Num. >>> > > > >>> > > > Best regards, >>> > > > Andrew >>> > > > >>> > > > >>> > > > _______________________________________________ >>> > > > 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 mblazevic at stilo.com Wed Feb 5 20:18:52 2020 From: mblazevic at stilo.com (=?UTF-8?Q?Mario_Bla=c5=beevi=c4=87?=) Date: Wed, 5 Feb 2020 15:18:52 -0500 Subject: Break `abs` into two aspects In-Reply-To: References: <2AD564B3-A853-4749-A48B-844DA40983DA@gmail.com> <0c092823-4fd6-fba3-cc93-dcb4d128fef5@ifi.lmu.de> Message-ID: <9ef1e52a-9373-9c4c-20dc-d2219e6ec93d@stilo.com> On 2020-02-04 11:32 a.m., Zemyla wrote: > It really doesn't matter if it's not "interesting" or not surjective for > some Semirings. It should be included, because: I fully agree, and I'll add another reason you left out. The presence of fromNatural would allow defaulting of Num's fromInteger as > fromInteger i > | i >= 0 = fromNatural (fromInteger i) > | otherwise = negate . fromInteger . negate $ i > (a) Even for semirings where it is "interesting", it's not surjective > (for instance, Rational or Double) > (b) It's a method with a default definition, so you don't have to expend > any mental effort on it > (c) A lot of instances have uninteresting methods: for instance, (*>) > and (<*) for Applicative ((->) e) are const id and const respectively. > Haskell adds methods to classes when they're always possible and > sometimes useful/interesting/faster, rather than when they're always > interesting. > (d) It's useful for Semiring-generic methods and instances. > (e) It can achieve an asymptotic speedup on some instances. Like, if you > have Semiring a => Semiring (f a) for some type f, then you can have > fromNatural n = pure (fromNatural n) instead of doing the whole O(log n) > song and dance with the default definition. Also, your example admits a > simple definition: >   fromNatural n = if n == 0 then S.empty else S.singleton True > (f) "zero" and "one" can be defined in terms of fromNatural, for > programmers who only need to define that: >   zero = fromNatural 0 >   one = fromNatural 1 > This leads to the MINIMAL pragma on Semiring being {-# MINIMAL plus, > times, (zero, one | fromNatural) #-} > (g) If it's not included in the class, but in some subclass > (NaturalSemiring, you proposed), but it's possible from the class, then > people will just define and use the O(log n) version instead of > requiring the subclass, leading to wasted effort and duplicated code. From carter.schonwald at gmail.com Thu Feb 6 01:19:37 2020 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Wed, 5 Feb 2020 20:19:37 -0500 Subject: Break `abs` into two aspects In-Reply-To: <9ef1e52a-9373-9c4c-20dc-d2219e6ec93d@stilo.com> References: <2AD564B3-A853-4749-A48B-844DA40983DA@gmail.com> <0c092823-4fd6-fba3-cc93-dcb4d128fef5@ifi.lmu.de> <9ef1e52a-9373-9c4c-20dc-d2219e6ec93d@stilo.com> Message-ID: Num doesn't have Ord as a parent constraint any more ... Though i suppose that works as a default signature instance? On Wed, Feb 5, 2020 at 3:19 PM Mario Blažević wrote: > On 2020-02-04 11:32 a.m., Zemyla wrote: > > It really doesn't matter if it's not "interesting" or not surjective for > > some Semirings. It should be included, because: > > I fully agree, and I'll add another reason you left out. The > presence > of fromNatural would allow defaulting of Num's fromInteger as > > > fromInteger i > > | i >= 0 = fromNatural (fromInteger i) > > | otherwise = negate . fromInteger . negate $ i > > > > (a) Even for semirings where it is "interesting", it's not surjective > > (for instance, Rational or Double) > > (b) It's a method with a default definition, so you don't have to expend > > any mental effort on it > > (c) A lot of instances have uninteresting methods: for instance, (*>) > > and (<*) for Applicative ((->) e) are const id and const respectively. > > Haskell adds methods to classes when they're always possible and > > sometimes useful/interesting/faster, rather than when they're always > > interesting. > > (d) It's useful for Semiring-generic methods and instances. > > (e) It can achieve an asymptotic speedup on some instances. Like, if you > > have Semiring a => Semiring (f a) for some type f, then you can have > > fromNatural n = pure (fromNatural n) instead of doing the whole O(log n) > > song and dance with the default definition. Also, your example admits a > > simple definition: > > fromNatural n = if n == 0 then S.empty else S.singleton True > > (f) "zero" and "one" can be defined in terms of fromNatural, for > > programmers who only need to define that: > > zero = fromNatural 0 > > one = fromNatural 1 > > This leads to the MINIMAL pragma on Semiring being {-# MINIMAL plus, > > times, (zero, one | fromNatural) #-} > > (g) If it's not included in the class, but in some subclass > > (NaturalSemiring, you proposed), but it's possible from the class, then > > people will just define and use the O(log n) version instead of > > requiring the subclass, leading to wasted effort and duplicated code. > > _______________________________________________ > 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 zemyla at gmail.com Thu Feb 6 02:08:24 2020 From: zemyla at gmail.com (Zemyla) Date: Wed, 5 Feb 2020 20:08:24 -0600 Subject: Break `abs` into two aspects In-Reply-To: References: <2AD564B3-A853-4749-A48B-844DA40983DA@gmail.com> <0c092823-4fd6-fba3-cc93-dcb4d128fef5@ifi.lmu.de> <9ef1e52a-9373-9c4c-20dc-d2219e6ec93d@stilo.com> Message-ID: "i" is an Integer there, which has an Ord instance. On Wed, Feb 5, 2020, 19:20 Carter Schonwald wrote: > Num doesn't have Ord as a parent constraint any more ... Though i suppose > that works as a default signature instance? > > On Wed, Feb 5, 2020 at 3:19 PM Mario Blažević wrote: > >> On 2020-02-04 11:32 a.m., Zemyla wrote: >> > It really doesn't matter if it's not "interesting" or not surjective >> for >> > some Semirings. It should be included, because: >> >> I fully agree, and I'll add another reason you left out. The >> presence >> of fromNatural would allow defaulting of Num's fromInteger as >> >> > fromInteger i >> > | i >= 0 = fromNatural (fromInteger i) >> > | otherwise = negate . fromInteger . negate $ i >> >> >> > (a) Even for semirings where it is "interesting", it's not surjective >> > (for instance, Rational or Double) >> > (b) It's a method with a default definition, so you don't have to >> expend >> > any mental effort on it >> > (c) A lot of instances have uninteresting methods: for instance, (*>) >> > and (<*) for Applicative ((->) e) are const id and const respectively. >> > Haskell adds methods to classes when they're always possible and >> > sometimes useful/interesting/faster, rather than when they're always >> > interesting. >> > (d) It's useful for Semiring-generic methods and instances. >> > (e) It can achieve an asymptotic speedup on some instances. Like, if >> you >> > have Semiring a => Semiring (f a) for some type f, then you can have >> > fromNatural n = pure (fromNatural n) instead of doing the whole O(log >> n) >> > song and dance with the default definition. Also, your example admits a >> > simple definition: >> > fromNatural n = if n == 0 then S.empty else S.singleton True >> > (f) "zero" and "one" can be defined in terms of fromNatural, for >> > programmers who only need to define that: >> > zero = fromNatural 0 >> > one = fromNatural 1 >> > This leads to the MINIMAL pragma on Semiring being {-# MINIMAL plus, >> > times, (zero, one | fromNatural) #-} >> > (g) If it's not included in the class, but in some subclass >> > (NaturalSemiring, you proposed), but it's possible from the class, then >> > people will just define and use the O(log n) version instead of >> > requiring the subclass, leading to wasted effort and duplicated code. >> >> _______________________________________________ >> 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 ndospark320 at gmail.com Thu Feb 6 03:44:11 2020 From: ndospark320 at gmail.com (Dannyu NDos) Date: Thu, 6 Feb 2020 12:44:11 +0900 Subject: Read (Ratio a) should also parse a decimal point literal Message-ID: Given a string representing a decimal point literal (ex. "0.25"), the number it represents is guaranteed to be rational. It seems appropriate for Ratio to parse such strings. readDecimalRatio :: (Integral a, Read a) => ReadPrec (Ratio a) readDecimalRatio = parens $ do Number x <- lexP return (numberToRational x) Combine this by (+++) with the original `readPrec` from the instance Read Ratio. -------------- next part -------------- An HTML attachment was scrubbed... URL: From a.pelenitsyn at gmail.com Fri Feb 7 02:47:29 2020 From: a.pelenitsyn at gmail.com (Artem Pelenitsyn) Date: Thu, 6 Feb 2020 21:47:29 -0500 Subject: Fwd: Misleading documentation for `fail` In-Reply-To: References: Message-ID: Hello, The fail package [1] lists libraries at haskell.org as maintainer's address, so I'm writing here. The documentation for the single module in the package claims: This module can be imported for defining forward compatible MonadFail instances: import qualified Control.Monad.Fail as Fail instance Monad Foo where (>>=) = {- ...bind impl... -} -- Provide legacy fail implementation for when -- new-style MonadFail desugaring is not enabled. fail = Fail.fail ... But defining the fail method inside a Monad instance will produce an error on GHC 8.8+. Should this bit be removed? -- Best, Artem [1]: http://hackage.haskell.org/package/fail -------------- next part -------------- An HTML attachment was scrubbed... URL: From andreas.abel at ifi.lmu.de Fri Feb 7 10:10:55 2020 From: andreas.abel at ifi.lmu.de (Andreas Abel) Date: Fri, 7 Feb 2020 11:10:55 +0100 Subject: Fwd: Misleading documentation for `fail` In-Reply-To: References: Message-ID: > error on GHC 8.8+. Should this bit be removed? I'd say it should be put under a suitable #if conditional. (For the sake of developers who wish to support many GHC versions.) On 2020-02-07 03:47, Artem Pelenitsyn wrote: > Hello, > > The fail package [1] lists libraries at haskell.org > as maintainer's address, so I'm writing > here. The documentation for the single module in the package claims: > > This module can be imported for defining forward compatible MonadFail > instances: > > import qualified Control.Monad.Fail as Fail > > instance Monad Foo where >   (>>=) = {- ...bind impl... -} > >   -- Provide legacy fail implementation for when >   -- new-style MonadFail desugaring is not enabled. >   fail = Fail.fail >   ... > > But defining the fail method inside a Monad instance will produce an > error on GHC 8.8+. Should this bit be removed? > > -- > Best, Artem > > [1]: http://hackage.haskell.org/package/fail > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > From ndospark320 at gmail.com Fri Feb 7 11:01:39 2020 From: ndospark320 at gmail.com (Dannyu NDos) Date: Fri, 7 Feb 2020 20:01:39 +0900 Subject: add instance PrintfArg Ratio Message-ID: It just is so convenient. instance (Integral a, Show a) => PrintfArg (Ratio a) where formatArg x f@(FieldFormat w p a s l _ c) = if elem c "gGv" then showsPrec 0 x else if elem c "doxXb" then formatArg (round x :: Integer) (f {fmtPrecision = Nothing, fmtChar = 'd'}) else case p of Nothing -> error "Text.Printf.formatArg: precision not given" Just p' -> if p' <= 0 then formatArg x (f {fmtPrecision = Nothing, fmtChar = 'd'}) else if elem c "fF" then let n = truncate x sig = '.' : goF (x - fromInteger n) p' b = case a of Just ZeroPad -> formatArg n (f {fmtWidth = fmap (subtract (length sig)) w, fmtPrecision = Nothing, fmtChar = 'd'}) "" _ -> show n in formatArg (b ++ sig) (f {fmtPrecision = Nothing, fmtChar = 's'}) else if elem c "eE" then let (q,e) = log10 x sig = c : show e a' = case a of Just ZeroPad -> a _ -> Nothing fp = formatArg q (f {fmtWidth = fmap (subtract (length sig)) w, fmtAdjust = a', fmtChar = 'f'}) "" in formatArg (fp ++ sig) (f {fmtPrecision = Nothing, fmtChar = 's'}) else error "Text.Printf.formatArg: bad format character" where goF _ 0 = "" goF x p = case compare x 0 of LT -> '-' : goF (negate x) p EQ -> "0" GT -> if 1 == p then show (round (10 * x) :: Integer) else let x10 = 10 * x n = truncate x10 in show n ++ goF (x10 - fromIntegral n) (p - 1) log10 x | x < 1 = let (q,e) = log10 (x * 10) in (q, e - 1) | 10 <= x = let (q,e) = log10 (x / 10) in (q, e + 1) | otherwise = (x, 0) -------------- next part -------------- An HTML attachment was scrubbed... URL: From carter.schonwald at gmail.com Fri Feb 7 15:01:21 2020 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Fri, 7 Feb 2020 10:01:21 -0500 Subject: Break `abs` into two aspects In-Reply-To: References: <2AD564B3-A853-4749-A48B-844DA40983DA@gmail.com> <0c092823-4fd6-fba3-cc93-dcb4d128fef5@ifi.lmu.de> <9ef1e52a-9373-9c4c-20dc-d2219e6ec93d@stilo.com> Message-ID: Derp. :) On Wed, Feb 5, 2020 at 9:08 PM Zemyla wrote: > "i" is an Integer there, which has an Ord instance. > > On Wed, Feb 5, 2020, 19:20 Carter Schonwald > wrote: > >> Num doesn't have Ord as a parent constraint any more ... Though i suppose >> that works as a default signature instance? >> >> On Wed, Feb 5, 2020 at 3:19 PM Mario Blažević >> wrote: >> >>> On 2020-02-04 11:32 a.m., Zemyla wrote: >>> > It really doesn't matter if it's not "interesting" or not surjective >>> for >>> > some Semirings. It should be included, because: >>> >>> I fully agree, and I'll add another reason you left out. The >>> presence >>> of fromNatural would allow defaulting of Num's fromInteger as >>> >>> > fromInteger i >>> > | i >= 0 = fromNatural (fromInteger i) >>> > | otherwise = negate . fromInteger . negate $ i >>> >>> >>> > (a) Even for semirings where it is "interesting", it's not surjective >>> > (for instance, Rational or Double) >>> > (b) It's a method with a default definition, so you don't have to >>> expend >>> > any mental effort on it >>> > (c) A lot of instances have uninteresting methods: for instance, (*>) >>> > and (<*) for Applicative ((->) e) are const id and const respectively. >>> > Haskell adds methods to classes when they're always possible and >>> > sometimes useful/interesting/faster, rather than when they're always >>> > interesting. >>> > (d) It's useful for Semiring-generic methods and instances. >>> > (e) It can achieve an asymptotic speedup on some instances. Like, if >>> you >>> > have Semiring a => Semiring (f a) for some type f, then you can have >>> > fromNatural n = pure (fromNatural n) instead of doing the whole O(log >>> n) >>> > song and dance with the default definition. Also, your example admits >>> a >>> > simple definition: >>> > fromNatural n = if n == 0 then S.empty else S.singleton True >>> > (f) "zero" and "one" can be defined in terms of fromNatural, for >>> > programmers who only need to define that: >>> > zero = fromNatural 0 >>> > one = fromNatural 1 >>> > This leads to the MINIMAL pragma on Semiring being {-# MINIMAL plus, >>> > times, (zero, one | fromNatural) #-} >>> > (g) If it's not included in the class, but in some subclass >>> > (NaturalSemiring, you proposed), but it's possible from the class, >>> then >>> > people will just define and use the O(log n) version instead of >>> > requiring the subclass, leading to wasted effort and duplicated code. >>> >>> _______________________________________________ >>> 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 carter.schonwald at gmail.com Fri Feb 7 18:59:58 2020 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Fri, 7 Feb 2020 13:59:58 -0500 Subject: deepseq: Add more instances. #50 In-Reply-To: References: Message-ID: aka, we shouldn't provide instances for stuff thats not "NF'able", so that these tricky bits aren't invisible, right? On Wed, Jan 15, 2020 at 8:37 PM Evan Laforge wrote: > As I understand, the case for against is: I have a space leak, I'll try > rnf on this data. Space leak is still present, so it must not be due to > that data, so I go to the next idea. But if there's something in there > that rnf silently skipped, then I'll be misled. It would be nice if the > compiler will warn me where the possibly leaking bits that rnf can't help > with, which is presumably closures and explicit pointers. > > On Wed, Jan 15, 2020, 3:43 AM Andrew Martin > wrote: > >> My understanding of the argument for and against is: >> >> * For: Typeclass instances should be provided for as many types as >> possible, and IORef, TVar, etc. only admit a single way to define NFData >> * Against: Intuitively, NFData means that data is plain old sums and >> products all the way down, all of which can be forced. This would mean that >> anything with an NFData instance should be able to go into a compact region >> (except that pinned byte arrays, and consequently bytestrings, cannot) >> >> I'm inclined to agree with most of the opinions expressed earlier on the >> thread. That is, given how minor the convenience is, the confusion is >> probably not worth the convenience. I'll think about this more today. >> >> On Tue, Jan 14, 2020 at 7:55 PM Travis Whitaker >> wrote: >> >>> Greetings Haskellers, >>> >>> I am writing to draw your attention to >>> https://github.com/haskell/deepseq/pull/50. >>> >>> This PR adds NFData instances for UArray, ForeignPtr, and TVar. The >>> instances for ForeignPtr and TVar have proven to be somewhat controversial. >>> I'll refer to these as "reference types" from here on out, since similar >>> concerns have been raised with respect to e.g. IORef. I think the arguments >>> presented here apply equally well to IORef. >>> >>> In summary: the argument against these instances is that rnf forces the >>> evaluation of the reference value itself, not the value referred to by the >>> reference. This is potentially confusing to NFData users. For example, a >>> user might expect that calling force on a TVar value will leave the value >>> to which the TVar refers in normal form. If this assumption doesn't hold, >>> the user's program will leak thunks. >>> >>> The argument for these instances is as follows: whether or not a >>> reference value is in normal form has nothing to do with whether or not the >>> referred-to value is in normal form. For example, consider ForeignPtr. >>> ForeignPtr's type constructor argument is just a phantom. Each ForeignPtr >>> value is just an Addr# with some finalizers. Whether or not these values >>> are in normal form has nothing to do with whether or not the value the >>> enclosed address may (or may not!) point to is in normal form. Indeed, an >>> NFData instance for ForeignPtr, TVar, or IORef that attempted to force the >>> referred-to value would require unsafe IO. >>> >>> I'm curious to hear other's thoughts about these arguments. I'm hopeful >>> that the proposed instances may be added, since I've encountered these >>> instances as orphans on numerous occasions. >>> >>> Thanks for your time, >>> >>> Travis Whitaker >>> _______________________________________________ >>> Libraries mailing list >>> Libraries at haskell.org >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >>> >> >> >> -- >> -Andrew Thaddeus Martin >> _______________________________________________ >> 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 carter.schonwald at gmail.com Fri Feb 7 19:00:40 2020 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Fri, 7 Feb 2020 14:00:40 -0500 Subject: deepseq: Add more instances. #50 In-Reply-To: References: Message-ID: "inNeeFable", i love this pun too much :) cf https://www.merriam-webster.com/dictionary/ineffable On Fri, Feb 7, 2020 at 1:59 PM Carter Schonwald wrote: > aka, we shouldn't provide instances for stuff thats not "NF'able", so that > these tricky bits aren't invisible, right? > > On Wed, Jan 15, 2020 at 8:37 PM Evan Laforge wrote: > >> As I understand, the case for against is: I have a space leak, I'll try >> rnf on this data. Space leak is still present, so it must not be due to >> that data, so I go to the next idea. But if there's something in there >> that rnf silently skipped, then I'll be misled. It would be nice if the >> compiler will warn me where the possibly leaking bits that rnf can't help >> with, which is presumably closures and explicit pointers. >> >> On Wed, Jan 15, 2020, 3:43 AM Andrew Martin >> wrote: >> >>> My understanding of the argument for and against is: >>> >>> * For: Typeclass instances should be provided for as many types as >>> possible, and IORef, TVar, etc. only admit a single way to define NFData >>> * Against: Intuitively, NFData means that data is plain old sums and >>> products all the way down, all of which can be forced. This would mean that >>> anything with an NFData instance should be able to go into a compact region >>> (except that pinned byte arrays, and consequently bytestrings, cannot) >>> >>> I'm inclined to agree with most of the opinions expressed earlier on the >>> thread. That is, given how minor the convenience is, the confusion is >>> probably not worth the convenience. I'll think about this more today. >>> >>> On Tue, Jan 14, 2020 at 7:55 PM Travis Whitaker >>> wrote: >>> >>>> Greetings Haskellers, >>>> >>>> I am writing to draw your attention to >>>> https://github.com/haskell/deepseq/pull/50. >>>> >>>> This PR adds NFData instances for UArray, ForeignPtr, and TVar. The >>>> instances for ForeignPtr and TVar have proven to be somewhat controversial. >>>> I'll refer to these as "reference types" from here on out, since similar >>>> concerns have been raised with respect to e.g. IORef. I think the arguments >>>> presented here apply equally well to IORef. >>>> >>>> In summary: the argument against these instances is that rnf forces the >>>> evaluation of the reference value itself, not the value referred to by the >>>> reference. This is potentially confusing to NFData users. For example, a >>>> user might expect that calling force on a TVar value will leave the value >>>> to which the TVar refers in normal form. If this assumption doesn't hold, >>>> the user's program will leak thunks. >>>> >>>> The argument for these instances is as follows: whether or not a >>>> reference value is in normal form has nothing to do with whether or not the >>>> referred-to value is in normal form. For example, consider ForeignPtr. >>>> ForeignPtr's type constructor argument is just a phantom. Each ForeignPtr >>>> value is just an Addr# with some finalizers. Whether or not these values >>>> are in normal form has nothing to do with whether or not the value the >>>> enclosed address may (or may not!) point to is in normal form. Indeed, an >>>> NFData instance for ForeignPtr, TVar, or IORef that attempted to force the >>>> referred-to value would require unsafe IO. >>>> >>>> I'm curious to hear other's thoughts about these arguments. I'm hopeful >>>> that the proposed instances may be added, since I've encountered these >>>> instances as orphans on numerous occasions. >>>> >>>> Thanks for your time, >>>> >>>> Travis Whitaker >>>> _______________________________________________ >>>> Libraries mailing list >>>> Libraries at haskell.org >>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >>>> >>> >>> >>> -- >>> -Andrew Thaddeus Martin >>> _______________________________________________ >>> 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 Fri Feb 7 21:44:14 2020 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Fri, 7 Feb 2020 22:44:14 +0100 (CET) Subject: add instance PrintfArg Ratio In-Reply-To: References: Message-ID: On Fri, 7 Feb 2020, Dannyu NDos wrote: > It just is so convenient. > > instance (Integral a, Show a) => PrintfArg (Ratio a) where Why should a Printf instance be base on Show? Wouldn't it better to format numerator and denominator using printf, too? From ndospark320 at gmail.com Fri Feb 7 23:40:28 2020 From: ndospark320 at gmail.com (Dannyu NDos) Date: Sat, 8 Feb 2020 08:40:28 +0900 Subject: Fwd: add instance PrintfArg Ratio In-Reply-To: References: Message-ID: ---------- Forwarded message --------- 보낸사람: Dannyu NDos Date: 2020년 2월 8일 (토) 오전 8:22 Subject: Re: add instance PrintfArg Ratio To: Henning Thielemann In that case, here (with some bugfixes): instance (Integral a, PrintfArg a) => PrintfArg (Ratio a) where formatArg x f@(FieldFormat w p a s l _ c) = if elem c "gGv" then let d = " % " ++ formatArg (denominator x) (FieldFormat Nothing Nothing Nothing s l "" 'd') "" (w',a') = case a of Just LeftAdjust -> (Nothing, Nothing) _ -> (fmap (subtract (length d)) w, a) n = formatArg (numerator x) (f {fmtWidth = w', fmtAdjust = a', fmtChar = 'd'}) "" in formatArg (n ++ d) (f {fmtPrecision = Nothing, fmtChar = 's'}) else if elem c "doxXb" then formatArg (round x :: Integer) f else case p of Nothing -> error "Text.Printf.formatArg: precision not given" Just p' -> if p' <= 0 then formatArg x (f {fmtPrecision = Nothing, fmtChar = 'd'}) else if elem c "fF" then let n = truncate x sig = '.' : goF (x - fromInteger n) p' (w',a') = case a of Just LeftAdjust -> (Nothing, Nothing) _ -> (fmap (subtract (length sig)) w, a) b = formatArg n (FieldFormat w' Nothing a' s l "" 'd') "" in formatArg (b ++ sig) (f {fmtPrecision = Nothing, fmtChar = 's'}) else if elem c "eE" then let (q,e) = log10 x sig = c : show e (w',a') = case a of Just LeftAdjust -> (Nothing, Nothing) _ -> (fmap (subtract (length sig)) w, a) fp = formatArg q (f {fmtWidth = w', fmtAdjust = a', fmtChar = 'f'}) "" in formatArg (fp ++ sig) (f {fmtPrecision = Nothing, fmtChar = 's'}) else error "Text.Printf.formatArg: bad format character" where goF _ 0 = "" goF x p = case compare x 0 of LT -> '-' : goF (negate x) p EQ -> "0" GT -> if 1 == p then show (round (10 * x) :: Integer) else let x10 = 10 * x n = truncate x10 in show n ++ goF (x10 - fromIntegral n) (p - 1) log10 x | x < 1 = let (q,e) = log10 (x * 10) in (q, e - 1) | 10 <= x = let (q,e) = log10 (x / 10) in (q, e + 1) | otherwise = (x, 0) 2020년 2월 8일 (토) 오전 6:44, Henning Thielemann 님이 작성: > > On Fri, 7 Feb 2020, Dannyu NDos wrote: > > > It just is so convenient. > > > > instance (Integral a, Show a) => PrintfArg (Ratio a) where > > Why should a Printf instance be base on Show? Wouldn't it better to format > numerator and denominator using printf, too? > -------------- next part -------------- An HTML attachment was scrubbed... URL: From carter.schonwald at gmail.com Sat Feb 8 00:37:04 2020 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Fri, 7 Feb 2020 19:37:04 -0500 Subject: I'm concerned about the affine-types extension and its impact on ghc and haskell at large Message-ID: https://github.com/ghc-proposals/ghc-proposals/pull/111#issuecomment-583664586 https://www.reddit.com/r/haskell/comments/f0jigv/im_concerned_about_the_longterm_impact_of_the/ As current maintainer of vector, and a member of the CLC, both of which roles really should be AFFIRMATIONAL stakeholders in this, I only see costs and concerns. As someone who's spent the past few years doing a LOT of modelling and prototyping around marrying linear logic, formal methods, and functional programming in an applied industrial setting, i should be an Affirmational stakeholder. yet again I am not. theres very real costs in the complexity and scope of impact that impact EVERY single user and stakeholder of ghc and haskell. And I do not see any concrete population that benefits. cale even makes a very constructive and articulate point > I don't know how much my opinion matters at this point, but I'd really like to see the non-toy real-world use cases of this before I can even consider thinking that it would be a good idea to merge to the main compiler. It has such a huge potential impact on so many people in the Haskell community: > > * Library maintainers who start getting PRs that make "improvements" to linearity while making their libraries harder to maintain because their interface becomes more rigid, and harder to understand because the types are more complicated. > > * Beginners, or simply ordinary users of the language who have to pay the mental overhead of living with the linear types and polymorphism spreading everywhere as types are adjusted to make terms more usable in places where one is concerned with linearity. > > * Commercial users of the language who pay for the additional time taken by all their employees waiting for the compiler to run, regardless of whether or not they're using the extension. If Carter's 6-7% slowdown is real even in cases where one doesn't care about the extension, I can imagine wanting to make a fork without the extension. The compiler is already 2 orders of magnitude slower than I'd like. If that weren't the case, maybe 6-7% wouldn't be a huge deal. While ghci is often helpful at shortening the feedback loop, it's not always a viable solution. > > > But really, I just want to know how anyone would put this to practical use in a real setting -- it needs to be _really_ compelling to make up for the social cost. It can't be that hard for Tweag, or someone enthusiastic, to live on a fork until they have a decent case study to show the world, so we can say "okay, that's actually really cool, maybe we actually want that everywhere". -------------- next part -------------- An HTML attachment was scrubbed... URL: From zemyla at gmail.com Sat Feb 8 19:36:41 2020 From: zemyla at gmail.com (Zemyla) Date: Sat, 8 Feb 2020 13:36:41 -0600 Subject: Break `abs` into two aspects In-Reply-To: References: <2AD564B3-A853-4749-A48B-844DA40983DA@gmail.com> <0c092823-4fd6-fba3-cc93-dcb4d128fef5@ifi.lmu.de> <9ef1e52a-9373-9c4c-20dc-d2219e6ec93d@stilo.com> Message-ID: Should we move the Semiring discussion to a new proposal? On Fri, Feb 7, 2020, 09:01 Carter Schonwald wrote: > Derp. :) > > On Wed, Feb 5, 2020 at 9:08 PM Zemyla wrote: > >> "i" is an Integer there, which has an Ord instance. >> >> On Wed, Feb 5, 2020, 19:20 Carter Schonwald >> wrote: >> >>> Num doesn't have Ord as a parent constraint any more ... Though i >>> suppose that works as a default signature instance? >>> >>> On Wed, Feb 5, 2020 at 3:19 PM Mario Blažević >>> wrote: >>> >>>> On 2020-02-04 11:32 a.m., Zemyla wrote: >>>> > It really doesn't matter if it's not "interesting" or not surjective >>>> for >>>> > some Semirings. It should be included, because: >>>> >>>> I fully agree, and I'll add another reason you left out. The >>>> presence >>>> of fromNatural would allow defaulting of Num's fromInteger as >>>> >>>> > fromInteger i >>>> > | i >= 0 = fromNatural (fromInteger i) >>>> > | otherwise = negate . fromInteger . negate $ i >>>> >>>> >>>> > (a) Even for semirings where it is "interesting", it's not surjective >>>> > (for instance, Rational or Double) >>>> > (b) It's a method with a default definition, so you don't have to >>>> expend >>>> > any mental effort on it >>>> > (c) A lot of instances have uninteresting methods: for instance, (*>) >>>> > and (<*) for Applicative ((->) e) are const id and const >>>> respectively. >>>> > Haskell adds methods to classes when they're always possible and >>>> > sometimes useful/interesting/faster, rather than when they're always >>>> > interesting. >>>> > (d) It's useful for Semiring-generic methods and instances. >>>> > (e) It can achieve an asymptotic speedup on some instances. Like, if >>>> you >>>> > have Semiring a => Semiring (f a) for some type f, then you can have >>>> > fromNatural n = pure (fromNatural n) instead of doing the whole O(log >>>> n) >>>> > song and dance with the default definition. Also, your example admits >>>> a >>>> > simple definition: >>>> > fromNatural n = if n == 0 then S.empty else S.singleton True >>>> > (f) "zero" and "one" can be defined in terms of fromNatural, for >>>> > programmers who only need to define that: >>>> > zero = fromNatural 0 >>>> > one = fromNatural 1 >>>> > This leads to the MINIMAL pragma on Semiring being {-# MINIMAL plus, >>>> > times, (zero, one | fromNatural) #-} >>>> > (g) If it's not included in the class, but in some subclass >>>> > (NaturalSemiring, you proposed), but it's possible from the class, >>>> then >>>> > people will just define and use the O(log n) version instead of >>>> > requiring the subclass, leading to wasted effort and duplicated code. >>>> >>>> _______________________________________________ >>>> 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 carter.schonwald at gmail.com Sat Feb 8 20:32:53 2020 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Sat, 8 Feb 2020 15:32:53 -0500 Subject: Break `abs` into two aspects In-Reply-To: References: <2AD564B3-A853-4749-A48B-844DA40983DA@gmail.com> <0c092823-4fd6-fba3-cc93-dcb4d128fef5@ifi.lmu.de> <9ef1e52a-9373-9c4c-20dc-d2219e6ec93d@stilo.com> Message-ID: Please do. On Sat, Feb 8, 2020 at 2:36 PM Zemyla wrote: > Should we move the Semiring discussion to a new proposal? > > On Fri, Feb 7, 2020, 09:01 Carter Schonwald > wrote: > >> Derp. :) >> >> On Wed, Feb 5, 2020 at 9:08 PM Zemyla wrote: >> >>> "i" is an Integer there, which has an Ord instance. >>> >>> On Wed, Feb 5, 2020, 19:20 Carter Schonwald >>> wrote: >>> >>>> Num doesn't have Ord as a parent constraint any more ... Though i >>>> suppose that works as a default signature instance? >>>> >>>> On Wed, Feb 5, 2020 at 3:19 PM Mario Blažević >>>> wrote: >>>> >>>>> On 2020-02-04 11:32 a.m., Zemyla wrote: >>>>> > It really doesn't matter if it's not "interesting" or not surjective >>>>> for >>>>> > some Semirings. It should be included, because: >>>>> >>>>> I fully agree, and I'll add another reason you left out. The >>>>> presence >>>>> of fromNatural would allow defaulting of Num's fromInteger as >>>>> >>>>> > fromInteger i >>>>> > | i >= 0 = fromNatural (fromInteger i) >>>>> > | otherwise = negate . fromInteger . negate $ i >>>>> >>>>> >>>>> > (a) Even for semirings where it is "interesting", it's not >>>>> surjective >>>>> > (for instance, Rational or Double) >>>>> > (b) It's a method with a default definition, so you don't have to >>>>> expend >>>>> > any mental effort on it >>>>> > (c) A lot of instances have uninteresting methods: for instance, >>>>> (*>) >>>>> > and (<*) for Applicative ((->) e) are const id and const >>>>> respectively. >>>>> > Haskell adds methods to classes when they're always possible and >>>>> > sometimes useful/interesting/faster, rather than when they're always >>>>> > interesting. >>>>> > (d) It's useful for Semiring-generic methods and instances. >>>>> > (e) It can achieve an asymptotic speedup on some instances. Like, if >>>>> you >>>>> > have Semiring a => Semiring (f a) for some type f, then you can have >>>>> > fromNatural n = pure (fromNatural n) instead of doing the whole >>>>> O(log n) >>>>> > song and dance with the default definition. Also, your example >>>>> admits a >>>>> > simple definition: >>>>> > fromNatural n = if n == 0 then S.empty else S.singleton True >>>>> > (f) "zero" and "one" can be defined in terms of fromNatural, for >>>>> > programmers who only need to define that: >>>>> > zero = fromNatural 0 >>>>> > one = fromNatural 1 >>>>> > This leads to the MINIMAL pragma on Semiring being {-# MINIMAL plus, >>>>> > times, (zero, one | fromNatural) #-} >>>>> > (g) If it's not included in the class, but in some subclass >>>>> > (NaturalSemiring, you proposed), but it's possible from the class, >>>>> then >>>>> > people will just define and use the O(log n) version instead of >>>>> > requiring the subclass, leading to wasted effort and duplicated code. >>>>> >>>>> _______________________________________________ >>>>> 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 0xd34df00d at gmail.com Sat Feb 8 22:34:17 2020 From: 0xd34df00d at gmail.com (Georg Rudoy) Date: Sat, 8 Feb 2020 17:34:17 -0500 Subject: Performance of `count`ing a char in a ByteString Message-ID: Hi there, tl;dr: I've noticed ByteString's `count`'s performance can be improved by a factor between 2.5 and 8 by explicitly using certain SIMD extensions, so what's the policy on those? Results of a small C benchmark (since the corresponding BS routine is implemented in C anyway) are available here ( https://github.com/0xd34df00d/counting-chars ), as well as some sample code to give the idea of what's happening (which might be incorrect/suboptimal, my SSE/AVX is rusty). I'll also put a sample input file if I manage to get git-lfs going. This change only really makes sense for large strings, but that's a somewhat common use case at least in my applications, so I wanted to gather some initial feedback, as well as ask a couple of questions and emphasize a couple of points. 1. How are SIMD extensions generally controlled? 2. Is depending on gcc OK? If so, we could leverage gcc's support of automatically generating a dispatching function that'll check cpuid for the supported extensions and call the right implementation. 3. Does BS' allocator give any guarantees on the alignment? It'd be nice to get rid of that "prefix" part that makes sure the SIMD code churns through 64-byte-aligned data. 4. Note that compiling with `-O3 -march=native` makes code effectively non-portable (at least, to CPUs lacking extensions the compiler decides to use), while the code with `-O2`, explicit SIMD versions and a dispatching function will get the best performance using the SIMD extensions available, degrading gracefully on older hardware. So, personally, when I look at that table with the results I compare the SSE4.2/AVX2 implementations against the `-O2` column. 5. Thanks Gregory Collins for mentioning PCMPESTRM somewhere — that remark sparked the desire to do some intrinsics stuff. -- Georg Rudoy From ndospark320 at gmail.com Sat Feb 8 22:48:12 2020 From: ndospark320 at gmail.com (Dannyu NDos) Date: Sun, 9 Feb 2020 07:48:12 +0900 Subject: add instance PrintfArg Ratio In-Reply-To: References: Message-ID: Faster version: instance (Integral a, PrintfArg a) => PrintfArg (Ratio a) where formatArg x f@(FieldFormat w p a s l _ c) = if elem c "gGv" then let d = " % " ++ formatArg (denominator x) (FieldFormat Nothing Nothing Nothing s l "" 'd') "" (w',a') = case a of Just LeftAdjust -> (Nothing, Nothing) _ -> (fmap (subtract (length d)) w, a) n = formatArg (numerator x) (f {fmtWidth = w', fmtAdjust = a', fmtChar = 'd'}) "" in formatArg (n ++ d) (f {fmtPrecision = Nothing, fmtChar = 's'}) else if elem c "doxXb" then formatArg (round x :: Integer) f else case p of Nothing -> error "Text.Printf.formatArg: precision not given" Just p' -> if p' <= 0 then formatArg x (f {fmtPrecision = Nothing, fmtChar = 'd'}) else if elem c "fF" then let n = truncate x sig = '.' : formatArg (round ((x - fromInteger n) * 10^p') :: Integer) (FieldFormat Nothing Nothing Nothing Nothing False "" 'd') "" (w',a') = case a of Just LeftAdjust -> (Nothing, Nothing) _ -> (fmap (subtract (length sig)) w, a) b = formatArg n (FieldFormat w' Nothing a' s l "" 'd') "" in formatArg (b ++ sig) (f {fmtPrecision = Nothing, fmtChar = 's'}) else if elem c "eE" then let (q,e) = log10 x sig = c : show e (w',a') = case a of Just LeftAdjust -> (Nothing, Nothing) _ -> (fmap (subtract (length sig)) w, a) fp = formatArg q (f {fmtWidth = w', fmtAdjust = a', fmtChar = 'f'}) "" in formatArg (fp ++ sig) (f {fmtPrecision = Nothing, fmtChar = 's'}) else error "Text.Printf.formatArg: bad format character" where goF _ 0 = "" goF x p = case compare x 0 of LT -> '-' : goF (negate x) p EQ -> "0" GT -> if 1 == p then show (round (10 * x) :: Integer) else let x10 = 10 * x n = truncate x10 in show n ++ goF (x10 - fromIntegral n) (p - 1) log10 x | x < 1 = let (q,e) = log10 (x * 10) in (q, e - 1) | 10 <= x = let (q,e) = log10 (x / 10) in (q, e + 1) | otherwise = (x, 0) 2020년 2월 8일 (토) 오전 8:40, Dannyu NDos 님이 작성: > > > ---------- Forwarded message --------- > 보낸사람: Dannyu NDos > Date: 2020년 2월 8일 (토) 오전 8:22 > Subject: Re: add instance PrintfArg Ratio > To: Henning Thielemann > > > In that case, here (with some bugfixes): > > instance (Integral a, PrintfArg a) => PrintfArg (Ratio a) where > formatArg x f@(FieldFormat w p a s l _ c) = if elem c "gGv" > then let > d = " % " ++ formatArg (denominator x) (FieldFormat Nothing > Nothing Nothing s l "" 'd') "" > (w',a') = case a of > Just LeftAdjust -> (Nothing, Nothing) > _ -> (fmap (subtract (length d)) w, a) > n = formatArg (numerator x) (f {fmtWidth = w', fmtAdjust = a', > fmtChar = 'd'}) "" > in formatArg (n ++ d) (f {fmtPrecision = Nothing, fmtChar = > 's'}) > else if elem c "doxXb" > then formatArg (round x :: Integer) f > else case p of > Nothing -> error "Text.Printf.formatArg: precision not > given" > Just p' -> if p' <= 0 > then formatArg x (f {fmtPrecision = Nothing, fmtChar = > 'd'}) > else if elem c "fF" > then let > n = truncate x > sig = '.' : goF (x - fromInteger n) p' > (w',a') = case a of > Just LeftAdjust -> (Nothing, Nothing) > _ -> (fmap (subtract (length sig)) w, a) > b = formatArg n (FieldFormat w' Nothing a' s l > "" 'd') "" > in formatArg (b ++ sig) (f {fmtPrecision = > Nothing, fmtChar = 's'}) > else if elem c "eE" > then let > (q,e) = log10 x > sig = c : show e > (w',a') = case a of > Just LeftAdjust -> (Nothing, Nothing) > _ -> (fmap (subtract (length sig)) w, > a) > fp = formatArg q (f {fmtWidth = w', > fmtAdjust = a', fmtChar = 'f'}) "" > in formatArg (fp ++ sig) (f {fmtPrecision > = Nothing, fmtChar = 's'}) > else error "Text.Printf.formatArg: bad format > character" > where > goF _ 0 = "" > goF x p = case compare x 0 of > LT -> '-' : goF (negate x) p > EQ -> "0" > GT -> if 1 == p > then show (round (10 * x) :: Integer) > else let > x10 = 10 * x > n = truncate x10 > in show n ++ goF (x10 - fromIntegral n) (p - 1) > log10 x > | x < 1 = let > (q,e) = log10 (x * 10) > in (q, e - 1) > | 10 <= x = let > (q,e) = log10 (x / 10) > in (q, e + 1) > | otherwise = (x, 0) > > 2020년 2월 8일 (토) 오전 6:44, Henning Thielemann 님이 > 작성: > >> >> On Fri, 7 Feb 2020, Dannyu NDos wrote: >> >> > It just is so convenient. >> > >> > instance (Integral a, Show a) => PrintfArg (Ratio a) where >> >> Why should a Printf instance be base on Show? Wouldn't it better to >> format >> numerator and denominator using printf, too? >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From vamchale at gmail.com Sat Feb 8 23:09:32 2020 From: vamchale at gmail.com (Vanessa McHale) Date: Sat, 8 Feb 2020 17:09:32 -0600 Subject: Performance of `count`ing a char in a ByteString In-Reply-To: References: Message-ID: <1966C8BB-1D8B-4F35-BF73-74C904561095@gmail.com> clang is the default C compiler on Mac. It would be sensible to at least support clang as well as gcc Cheers, Vanessa McHale > On Feb 8, 2020, at 4:34 PM, Georg Rudoy <0xd34df00d at gmail.com> wrote: > > Hi there, > > tl;dr: I've noticed ByteString's `count`'s performance can be improved > by a factor between 2.5 and 8 by explicitly using certain SIMD > extensions, so what's the policy on those? > > Results of a small C benchmark (since the corresponding BS routine is > implemented in C anyway) are available here ( > https://github.com/0xd34df00d/counting-chars ), as well as some sample > code to give the idea of what's happening (which might be > incorrect/suboptimal, my SSE/AVX is rusty). I'll also put a sample > input file if I manage to get git-lfs going. > > This change only really makes sense for large strings, but that's a > somewhat common use case at least in my applications, so I wanted to > gather some initial feedback, as well as ask a couple of questions and > emphasize a couple of points. > > 1. How are SIMD extensions generally controlled? > > 2. Is depending on gcc OK? If so, we could leverage gcc's support of > automatically generating a dispatching function that'll check cpuid > for the supported extensions and call the right implementation. > > 3. Does BS' allocator give any guarantees on the alignment? It'd be > nice to get rid of that "prefix" part that makes sure the SIMD code > churns through 64-byte-aligned data. > > 4. Note that compiling with `-O3 -march=native` makes code effectively > non-portable (at least, to CPUs lacking extensions the compiler > decides to use), while the code with `-O2`, explicit SIMD versions and > a dispatching function will get the best performance using the SIMD > extensions available, degrading gracefully on older hardware. So, > personally, when I look at that table with the results I compare the > SSE4.2/AVX2 implementations against the `-O2` column. > > 5. Thanks Gregory Collins for mentioning PCMPESTRM somewhere — that > remark sparked the desire to do some intrinsics stuff. > > -- > Georg Rudoy > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries From 0xd34df00d at gmail.com Sat Feb 8 23:35:03 2020 From: 0xd34df00d at gmail.com (Georg Rudoy) Date: Sat, 8 Feb 2020 18:35:03 -0500 Subject: Performance of `count`ing a char in a ByteString In-Reply-To: <1966C8BB-1D8B-4F35-BF73-74C904561095@gmail.com> References: <1966C8BB-1D8B-4F35-BF73-74C904561095@gmail.com> Message-ID: Totally forgot about that, thanks for pointing out! Manual dispatch it is then — a bit less pleasant, but not too bad. сб, 8 февр. 2020 г., 18:09 Vanessa McHale : > > clang is the default C compiler on Mac. It would be sensible to at least support clang as well as gcc > > Cheers, > Vanessa McHale > > > On Feb 8, 2020, at 4:34 PM, Georg Rudoy <0xd34df00d at gmail.com> wrote: > > > > Hi there, > > > > tl;dr: I've noticed ByteString's `count`'s performance can be improved > > by a factor between 2.5 and 8 by explicitly using certain SIMD > > extensions, so what's the policy on those? > > > > Results of a small C benchmark (since the corresponding BS routine is > > implemented in C anyway) are available here ( > > https://github.com/0xd34df00d/counting-chars ), as well as some sample > > code to give the idea of what's happening (which might be > > incorrect/suboptimal, my SSE/AVX is rusty). I'll also put a sample > > input file if I manage to get git-lfs going. > > > > This change only really makes sense for large strings, but that's a > > somewhat common use case at least in my applications, so I wanted to > > gather some initial feedback, as well as ask a couple of questions and > > emphasize a couple of points. > > > > 1. How are SIMD extensions generally controlled? > > > > 2. Is depending on gcc OK? If so, we could leverage gcc's support of > > automatically generating a dispatching function that'll check cpuid > > for the supported extensions and call the right implementation. > > > > 3. Does BS' allocator give any guarantees on the alignment? It'd be > > nice to get rid of that "prefix" part that makes sure the SIMD code > > churns through 64-byte-aligned data. > > > > 4. Note that compiling with `-O3 -march=native` makes code effectively > > non-portable (at least, to CPUs lacking extensions the compiler > > decides to use), while the code with `-O2`, explicit SIMD versions and > > a dispatching function will get the best performance using the SIMD > > extensions available, degrading gracefully on older hardware. So, > > personally, when I look at that table with the results I compare the > > SSE4.2/AVX2 implementations against the `-O2` column. > > > > 5. Thanks Gregory Collins for mentioning PCMPESTRM somewhere — that > > remark sparked the desire to do some intrinsics stuff. > > > > -- > > Georg Rudoy > > _______________________________________________ > > Libraries mailing list > > Libraries at haskell.org > > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > From ndospark320 at gmail.com Sun Feb 9 06:14:52 2020 From: ndospark320 at gmail.com (Dannyu NDos) Date: Sun, 9 Feb 2020 15:14:52 +0900 Subject: Fwd: add instance PrintfArg Ratio In-Reply-To: References: Message-ID: ---------- Forwarded message --------- 보낸사람: Dannyu NDos Date: 2020년 2월 9일 (일) 오후 3:14 Subject: Re: add instance PrintfArg Ratio To: Henning Thielemann Bugfix: instance (Integral a, PrintfArg a) => PrintfArg (Ratio a) where formatArg x f@(FieldFormat w p a s l _ c) = if elem c "gGv" then let d = " % " ++ formatArg (denominator x) (FieldFormat Nothing Nothing Nothing s l "" 'd') "" (w',a') = case a of Just LeftAdjust -> (Nothing, Nothing) _ -> (fmap (subtract (length d)) w, a) n = formatArg (numerator x) (f {fmtWidth = w', fmtAdjust = a', fmtChar = 'd'}) "" in formatArg (n ++ d) (f {fmtPrecision = Nothing, fmtChar = 's'}) else if elem c "doxXb" then formatArg (round x :: Integer) f else case p of Nothing -> error "Text.Printf.formatArg: precision not given" Just p' -> if p' <= 0 then formatArg x (f {fmtPrecision = Nothing, fmtChar = 'd'}) else if elem c "fF" then let a' = case a of Just LeftAdjust -> Nothing _ -> a digits = formatArg (truncate (x * 10 ^ p') :: Integer) (f {fmtPrecision = Nothing, fmtAdjust = a', fmtChar = 'd'}) "" (n,sig) = splitAt (length digits - p') digits in formatArg (n ++ '.' : sig) (f {fmtPrecision = Nothing, fmtChar = 's'}) else if elem c "eE" then let (q,e) = log10 x sig = c : show e (w',a') = case a of Just LeftAdjust -> (Nothing, Nothing) _ -> (fmap (subtract (length sig)) w, a) fp = formatArg q (f {fmtWidth = w', fmtAdjust = a', fmtChar = 'f'}) "" in formatArg (fp ++ sig) (f {fmtPrecision = Nothing, fmtChar = 's'}) else error "Text.Printf.formatArg: bad format character" where goF _ 0 = "" goF x p = case compare x 0 of LT -> '-' : goF (negate x) p EQ -> "0" GT -> if 1 == p then show (round (10 * x) :: Integer) else let x10 = 10 * x n = truncate x10 in show n ++ goF (x10 - fromIntegral n) (p - 1) log10 x | x < 1 = let (q,e) = log10 (x * 10) in (q, e - 1) | 10 <= x = let (q,e) = log10 (x / 10) in (q, e + 1) | otherwise = (x, 0) -------------- next part -------------- An HTML attachment was scrubbed... URL: From ndospark320 at gmail.com Sun Feb 9 10:19:17 2020 From: ndospark320 at gmail.com (Dannyu NDos) Date: Sun, 9 Feb 2020 19:19:17 +0900 Subject: add instance PrintfArg Ratio In-Reply-To: References: Message-ID: Bugfix: use round instead of truncate. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ndospark320 at gmail.com Sun Feb 9 10:20:28 2020 From: ndospark320 at gmail.com (Dannyu NDos) Date: Sun, 9 Feb 2020 19:20:28 +0900 Subject: add instance PrintfArg Ratio In-Reply-To: References: Message-ID: Also goF is no longer needed. 2020년 2월 9일 (일) 오후 7:19, Dannyu NDos 님이 작성: > Bugfix: use round instead of truncate. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From andreas.abel at ifi.lmu.de Mon Feb 10 18:21:57 2020 From: andreas.abel at ifi.lmu.de (Andreas Abel) Date: Mon, 10 Feb 2020 19:21:57 +0100 Subject: add instance PrintfArg Ratio In-Reply-To: References: Message-ID: The libraries at haskell.org mailing list is not a forum to develop and debug haskell functions. Please refrain from further updates on your development process. Once the proposal is mature and secured by a testsuite it makes sense to subject it again to discussion on this mailing list. Thanks, Andreas On 2020-02-09 11:20, Dannyu NDos wrote: > Also goF is no longer needed. > > 2020년 2월 9일 (일) 오후 7:19, Dannyu NDos >님이 작성: > > Bugfix: use round instead of truncate. > > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > From alexandreR_B at outlook.com Mon Feb 10 21:41:38 2020 From: alexandreR_B at outlook.com (=?utf-8?B?QWxleGFuZHJlIFJvZHJpZ3VlcyBCYWxkw6k=?=) Date: Mon, 10 Feb 2020 21:41:38 +0000 Subject: add instance PrintfArg Ratio In-Reply-To: References: , Message-ID: Hello Andreas, I’m also part of this mailing list, and while I agree with what you just said, I believe the tone of your message was slightly unfriendly (though still polite). I hope you do not mind this comment – as you said, there are certainly more appropriate venues for the contents of this email thread. However, the best part about our community is, I think, (still) the kind way in which we treat each other. Cheers ________________________________ De: Libraries em nome de Andreas Abel Enviado: Monday, February 10, 2020 6:21:57 PM Para: libraries at haskell.org Assunto: Re: add instance PrintfArg Ratio The libraries at haskell.org mailing list is not a forum to develop and debug haskell functions. Please refrain from further updates on your development process. Once the proposal is mature and secured by a testsuite it makes sense to subject it again to discussion on this mailing list. Thanks, Andreas On 2020-02-09 11:20, Dannyu NDos wrote: > Also goF is no longer needed. > > 2020년 2월 9일 (일) 오후 7:19, Dannyu NDos >님이 작성: > > Bugfix: use round instead of truncate. > > > _______________________________________________ > 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 byorgey at gmail.com Thu Feb 13 11:48:02 2020 From: byorgey at gmail.com (Brent Yorgey) Date: Thu, 13 Feb 2020 05:48:02 -0600 Subject: Taking over maintainership of cautious-file (or does anyone know of an alternative?) Message-ID: The cautious-file package http://hackage.haskell.org/package/cautious-file has not been updated by the maintainer, Robin Green, since 2013 (though there have been a few Hackage trustee updates since then). The linked source repository was hosted on patch-tag.com and no longer exists. I tried contacting the maintainer on January 25 but have not heard back. I hereby announce my intention to take over as maintainer of the package. (As a side note, as far as I know my diagrams-haddock package is the only thing on Hackage that depends on it.) Alternatively, if anyone knows of a different, actively maintained package that provides similar functionality, I'd love to hear about it! -Brent -------------- next part -------------- An HTML attachment was scrubbed... URL: From oleg.grenrus at iki.fi Thu Feb 13 12:00:31 2020 From: oleg.grenrus at iki.fi (Oleg Grenrus) Date: Thu, 13 Feb 2020 14:00:31 +0200 Subject: Taking over maintainership of cautious-file (or does anyone know of an alternative?) In-Reply-To: References: Message-ID: <1d08345d-d41b-a4bd-b357-85155a145a66@iki.fi> Based on https://packdeps.haskellers.com/reverse/cautious-file the only other dependency is tbox, which haven't been updated since 2010. I think we don't need to wait very long on this, yethttps://github.com/greenrd have been active in the past year, hopefully these emails reach him. - Oleg On 13.2.2020 13.48, Brent Yorgey wrote: > The cautious-file package > > http://hackage.haskell.org/package/cautious-file > > has not been updated by the maintainer, Robin Green, since 2013 > (though there have been a few Hackage trustee updates since then).  > The linked source repository was hosted on patch-tag.com > and no longer exists.  I tried contacting the > maintainer on January 25 but have not heard back. > > I hereby announce my intention to take over as maintainer of the > package.  (As a side note, as far as I know my diagrams-haddock > package is the only thing on Hackage that depends on it.) > > Alternatively, if anyone knows of a different, actively maintained > package that provides similar functionality, I'd love to hear about it! > > -Brent > > _______________________________________________ > 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 nh2.me Thu Feb 13 16:43:46 2020 From: mail at nh2.me (=?UTF-8?Q?Niklas_Hamb=c3=bcchen?=) Date: Thu, 13 Feb 2020 17:43:46 +0100 Subject: [Haskell-cafe] Taking over maintainership of cautious-file (or does anyone know of an alternative?) In-Reply-To: References: Message-ID: <89f8c534-b4f4-3296-8b56-127f5c2bf994@nh2.me> Tangentially, note that `cautious-file` has drawbacks: * It is not async-exception safe and may leak file descriptors. It uses `handleToFd` without proper exception handling (`bracket`). * It does not `fsync` the directory in which the file is, meaning that you may still experience data loss on computer crashes. `unliftio` provides actively maintained versions of most of what `cautious-file` does, addresses those drawbacks and is well-tested against crashes: https://hackage.haskell.org/package/unliftio-0.2.12/docs/UnliftIO-IO-File.html For example, `writeBinaryFileDurableAtomic`. Niklas From carter.schonwald at gmail.com Thu Feb 13 22:17:00 2020 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Thu, 13 Feb 2020 17:17:00 -0500 Subject: [core libraries] Rename NonEmpty.groupWith/sortWIth to *On* In-Reply-To: References: Message-ID: Hello Philip, clc gets / reads libraries anyways, no need to double email : ) perhaps i'm missing something, are we talking about the specifics of the implementations while stilling having the same observable pure results, OR something different? When does each have a clear performance win? at least from my native english speaker perspective, sortWith is better grammar. Are you describing a choice of performance characteristics related to *On vs *With functions? also, could you spell out which reference implementations of which convention enshrine which meanings you have in mind? I dont see a good reason to change the names that are provided from one to the other. Are you merely making the case that both styles should be exported from certain places, and that a particular choice of evaluation trade offs be enshrined by the respective naming convention? please spell this out more concretely, i'm not able to decode what you mean unambiguiously. Just changing the names of some functions in base in isolation breaks code for no reason, so if you are arguing for that, i'm gonna say nope :) On Wed, Feb 12, 2020 at 12:58 PM Philip Hazelden wrote: > Hi, > > I'm referring to these functions: `sortWith` `groupWith` `groupAllWith` > `groupWith1` `groupAllWith1`. > > The `On` suffix is more common for such things, and I anticipate it's what > most users will normally expect them to be named. > > Additionally, the name `groupWith` is potentially misleading. That name is > also used in GHC.Exts[1], for a function with the same type signature but > different semantics. `GHC.Exts.groupWith` sorts its input list, unlike > `NonEmpty.groupWith` or `Data.List.Extra.groupOn`. (In NonEmpty, we have > `groupAllWith` for group-with-sort. So we have three names, two semantics, > and no consistency.) > > According to https://github.com/ekmett/semigroups/pull/52, `With` was > chosen because: > > > The preferred vocabulary for On here is With to match the combinators in > GHC.Exts from the "comprehensive comprehensions" paper. That'd make it so > that if you use these with comprehensive comprehensions turned on and > RebindableSyntax turned on then you'd get these combinators. > > But I don't see anything in the docs which suggests that the > TransformListComp extension[2] uses these functions implicitly, or > interacts with RebindableSyntax[3]. So perhaps I'm missing something, but > my guess is this is no longer a concern. > > The case for `sortWith` is weaker, since it might trip people up but it > won't introduce unexpected semantics. There's also a counter argument in > https://gitlab.haskell.org/ghc/ghc/issues/12044. `Data.List.sortOn` only > computes the mapping function once for each element, while > `GHC.Exts.sortWith` computes it every time it does a comparison but uses > fewer allocations. `Data.NonEmpty.sortWith` acts like the latter. My > suggestion would be to replace it with a `sortOn` implemented like > `Data.List.sortOn`, but I also don't think it would be terrible to have > both, or even to just rename and leave this small inconsistency. If there's > no agreement on this function, I think it would be worth renaming the group > functions anyway. > > And so I propose, in descending order of how much I care: > > 1. Rename the group functions to be named "On" instead of "With". > > 2. Rename `sortWith` to `sortOn` In the case of `sortWith`, also > reimplement it as > > 3. Reimplement `sortOn` as > > sortOn :: Ord b => (a -> b) -> NonEmpty a -> NonEmpty a > sortOn = fmap snd . sortBy (comparing fst) . fmap (\x -> let y = f x > in y `seq` (y, x)) > > I assume the process here would be to leave the existing names for a time > with deprecation warnings, and then remove them a few versions down the > line. > > [1] > https://hackage.haskell.org/package/base-4.12.0.0/docs/GHC-Exts.html#v:groupWith > [2] > https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#extension-TransformListComp > [3] > https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#extension-RebindableSyntax > > Best, > Phil > > -- > You received this message because you are subscribed to the Google Groups > "haskell-core-libraries" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to haskell-core-libraries+unsubscribe at googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/haskell-core-libraries/CALB5dS-5qKjK6rmvFg2TuZ_3HvPtPyuGzsTrVO8adAnX1zovdg%40mail.gmail.com > > . > -------------- next part -------------- An HTML attachment was scrubbed... URL: From byorgey at gmail.com Thu Feb 13 22:27:16 2020 From: byorgey at gmail.com (Brent Yorgey) Date: Thu, 13 Feb 2020 16:27:16 -0600 Subject: [Haskell-cafe] Taking over maintainership of cautious-file (or does anyone know of an alternative?) In-Reply-To: <89f8c534-b4f4-3296-8b56-127f5c2bf994@nh2.me> References: <89f8c534-b4f4-3296-8b56-127f5c2bf994@nh2.me> Message-ID: Perfect, thanks! I will try switching over to use unliftio. Assuming it meets my needs --- and I see no reason why it won't --- I withdraw my intention to take over cautious-file. -Brent On Thu, Feb 13, 2020 at 10:43 AM Niklas Hambüchen wrote: > Tangentially, note that `cautious-file` has drawbacks: > > * It is not async-exception safe and may leak file descriptors. It uses > `handleToFd` without proper exception handling (`bracket`). > * It does not `fsync` the directory in which the file is, meaning that you > may still experience data loss on computer crashes. > > `unliftio` provides actively maintained versions of most of what > `cautious-file` does, addresses those drawbacks and is well-tested against > crashes: > > > https://hackage.haskell.org/package/unliftio-0.2.12/docs/UnliftIO-IO-File.html > > For example, `writeBinaryFileDurableAtomic`. > > Niklas > -------------- next part -------------- An HTML attachment was scrubbed... URL: From carter.schonwald at gmail.com Sat Feb 15 13:00:20 2020 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Sat, 15 Feb 2020 08:00:20 -0500 Subject: [core libraries] Rename NonEmpty.groupWith/sortWIth to *On* In-Reply-To: References: Message-ID: I think I follow. Pedantic point : when you say semantics, it might be less confusing and more precise to performance tradeoffs. My English language and naive preference is to assume *With functions grammar better. Or *by. I think the *on idiom is younger relatively. Can I challenge you to reflect on what challenge you are trying to address with this proposal and if there’s a course of action that you feel improves everything but breaks no code ? And what would make the change an improvement for software using these modules already On Sat, Feb 15, 2020 at 7:36 AM Philip Hazelden wrote: > Hi, > > > clc gets / reads libraries anyways, no need to double email : ) > > Fair enough. I tried to follow the process suggested at > https://wiki.haskell.org/Core_Libraries_Committee by emailing both lists. > I was surprised that the mail to libraries@ got rejected. No big deal, > but should that page be updated? > > > are we talking about the specifics of the implementations while stilling > having the same observable pure results, OR something different? > > For sortWith/sortOn, yeah, my proposal #3 would change performance > characteristics but not the pure semantics. > > The existing functions that we have are > > Data.List.sortOn f = > map snd . sortBy (comparing fst) . map (\x -> let y = f x in y `seq` > (y, x)) > GHC.Exts.sortWith f = sortBy (\x y -> compare (f x) (f y)) > Data.List.NonEmpty.sortWith = sortBy . comparing > > Where the first two have type signature `Ord b :: (a -> b) -> [a] -> [a]` > and the last is `Ord b :: (a -> b) -> NonEmpty a -> NonEmpty a`. > > Data.List.sortOn is implemented in a way that calls its projection > function just once per list element, but it allocates an intermediate list. > If the projection function is expensive, that'll be worth it. The style of > the functions named sortWith avoids the intermediate list, but at the cost > of calling the projection twice for each comparison; so that'll be better > if the projection is cheap. > > I bring this up because issue 12044 suggested removing `GHC.Exts.sortWith` > for being semantically the same as `Data.List.sortOn`, and the performance > question was brought up there. To be clear, I don't think it's a big deal. > > > please spell this out more concretely, i'm not able to decode what you > mean unambiguiously. Just changing the names of some functions in base in > isolation breaks code for no reason, > > My proposals #1 and #2 are just to change the names of functions, yeah. > But it's not for no reason. > > There are two problems with the current names. The smaller one, applying > to all of these functions, is that I believe the "On" pattern is more > widely used. And so if a user tries to guess what these functions will be > called, they'll most likely go for that. > > (I don't have any hard data here, admittedly. We see "On" in > Data.List.sortOn, but also many functions in Data.List.Extra like `nubOn`, > `groupOn`, `maximumOn`. Admittedly that's not in base. But I'll also note > that NonEmpty.sortWith was originally called sortOn, and the groupWith > functions were originally requested with the name groupOn; see > https://github.com/ekmett/semigroups/pull/52. So yeah, my sense is that > "On" is what most people will expect.) > > The more significant one, applying to the group functions but not to > sortWith, is that the only other function in base named `groupWith` has a > comparable type signature but different semantics. > Data.List.NonEmpty.groupWith is "group according to a projection function" > while GHC.Exts.groupWith is "sort and group according to a projection > function". If someone gets these behaviours confused, they're going to sort > when they don't intend to, or to not sort when they do intend to. Using > more consistent naming may help avoid that. > > It may be that this isn't enough reason to break code. If the committee > decides that it's not, then fair enough. > > Though, it now occurs to me that renaming `GHC.Exts.groupWith` to > `groupAllOn` or `groupAllWith` or something (in Data.List.Extra it's named > "groupSortOn"), could also help clear up the larger problem while breaking > less code. So I'll offer that possibility for consideration too. > > > > On Thu, Feb 13, 2020 at 10:17 PM Carter Schonwald < > carter.schonwald at gmail.com> wrote: > >> Hello Philip, clc gets / reads libraries anyways, no need to double email >> : ) >> >> perhaps i'm missing something, are we talking about the specifics of the >> implementations while stilling having the same observable pure results, OR >> something different? >> >> When does each have a clear performance win? >> >> at least from my native english speaker perspective, sortWith is better >> grammar. Are you describing a choice of performance characteristics >> related to *On vs *With functions? >> >> also, could you spell out which reference implementations of which >> convention enshrine which meanings you have in mind? >> >> I dont see a good reason to change the names that are provided from one >> to the other. Are you merely making the case that both styles should be >> exported from certain places, and that a particular choice of evaluation >> trade offs be enshrined by the respective naming convention? >> >> >> please spell this out more concretely, i'm not able to decode what you >> mean unambiguiously. Just changing the names of some functions in base in >> isolation breaks code for no reason, so if you are arguing for that, i'm >> gonna say nope :) >> >> On Wed, Feb 12, 2020 at 12:58 PM Philip Hazelden < >> philip.hazelden at gmail.com> wrote: >> >>> Hi, >>> >>> I'm referring to these functions: `sortWith` `groupWith` `groupAllWith` >>> `groupWith1` `groupAllWith1`. >>> >>> The `On` suffix is more common for such things, and I anticipate it's >>> what most users will normally expect them to be named. >>> >>> Additionally, the name `groupWith` is potentially misleading. That name >>> is also used in GHC.Exts[1], for a function with the same type signature >>> but different semantics. `GHC.Exts.groupWith` sorts its input list, unlike >>> `NonEmpty.groupWith` or `Data.List.Extra.groupOn`. (In NonEmpty, we have >>> `groupAllWith` for group-with-sort. So we have three names, two semantics, >>> and no consistency.) >>> >>> According to https://github.com/ekmett/semigroups/pull/52, `With` was >>> chosen because: >>> >>> > The preferred vocabulary for On here is With to match the combinators >>> in GHC.Exts from the "comprehensive comprehensions" paper. That'd make it >>> so that if you use these with comprehensive comprehensions turned on and >>> RebindableSyntax turned on then you'd get these combinators. >>> >>> But I don't see anything in the docs which suggests that the >>> TransformListComp extension[2] uses these functions implicitly, or >>> interacts with RebindableSyntax[3]. So perhaps I'm missing something, but >>> my guess is this is no longer a concern. >>> >>> The case for `sortWith` is weaker, since it might trip people up but it >>> won't introduce unexpected semantics. There's also a counter argument in >>> https://gitlab.haskell.org/ghc/ghc/issues/12044. `Data.List.sortOn` >>> only computes the mapping function once for each element, while >>> `GHC.Exts.sortWith` computes it every time it does a comparison but uses >>> fewer allocations. `Data.NonEmpty.sortWith` acts like the latter. My >>> suggestion would be to replace it with a `sortOn` implemented like >>> `Data.List.sortOn`, but I also don't think it would be terrible to have >>> both, or even to just rename and leave this small inconsistency. If there's >>> no agreement on this function, I think it would be worth renaming the group >>> functions anyway. >>> >>> And so I propose, in descending order of how much I care: >>> >>> 1. Rename the group functions to be named "On" instead of "With". >>> >>> 2. Rename `sortWith` to `sortOn` In the case of `sortWith`, also >>> reimplement it as >>> >>> 3. Reimplement `sortOn` as >>> >>> sortOn :: Ord b => (a -> b) -> NonEmpty a -> NonEmpty a >>> sortOn = fmap snd . sortBy (comparing fst) . fmap (\x -> let y = f x >>> in y `seq` (y, x)) >>> >>> I assume the process here would be to leave the existing names for a >>> time with deprecation warnings, and then remove them a few versions down >>> the line. >>> >>> [1] >>> https://hackage.haskell.org/package/base-4.12.0.0/docs/GHC-Exts.html#v:groupWith >>> [2] >>> https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#extension-TransformListComp >>> [3] >>> https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#extension-RebindableSyntax >>> >>> Best, >>> Phil >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "haskell-core-libraries" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to haskell-core-libraries+unsubscribe at googlegroups.com. >>> To view this discussion on the web visit >>> https://groups.google.com/d/msgid/haskell-core-libraries/CALB5dS-5qKjK6rmvFg2TuZ_3HvPtPyuGzsTrVO8adAnX1zovdg%40mail.gmail.com >>> >>> . >>> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From philip.hazelden at gmail.com Sat Feb 15 18:58:39 2020 From: philip.hazelden at gmail.com (Philip Hazelden) Date: Sat, 15 Feb 2020 18:58:39 +0000 Subject: [core libraries] Rename NonEmpty.groupWith/sortWIth to *On* In-Reply-To: References: Message-ID: Hi, On Sat, Feb 15, 2020 at 1:00 PM Carter Schonwald wrote: > Pedantic point : when you say semantics, it might be less confusing and > more precise to performance tradeoffs. > Apologies, but I'm not sure what you mean here. Could you rephrase? > My English language and naive preference is to assume *With functions > grammar better. Or *by. I think the *on idiom is younger relatively. > I don't personally have an a particular preference between *With and *On, just a preference for consistency. My proposal isn't motivated by the english meanings of the words "with" and "on", just by (my perception of) their current usage in the ecosystem. If *With was used in most places, and *On was used in Data.List.NonEmpty, then I'd recommend switching NonEmpty to *With. (*By is already taken: `sortBy`, `nubBy`, `groupBy` and so on. That does seem to be already consistent.) An advantage of *On is that it reflects how the functions can be defined using the `on` function: sortOn f = sortBy (compare `on` f) groupOn f = groupBy ((==) `on` f) Historically, it does look like *With has been in use longer. (It looks like `sortOn` has been in base since 4.8 (2015), and in the "extra" package since the very first version 0.1 in 2014. `sortWith` has been in GHC.Exts since at least base 4.0 in 2009.) But again, neither of those points factors into my motivation here. > Can I challenge you to reflect on what challenge you are trying to > address with this proposal and if there’s a course of action that you feel > improves everything but breaks no code ? > I suppose that simply adding the new names, marking the old ones as deprecated, and then never actually removing the old ones, would work for that. > And what would make the change an improvement for software using these > modules already > Well, a small one is that it would make that software slightly easier to read for people who recognize the *On convention but not the *With one. There's also a chance it would make a small number of people notice that they were using a function that had different semantics from what they thought, catching bugs that hadn't previously surfaced. But I don't think there's any version of this proposal that would accomplish this in any significant way. Improving existing software isn't really the point. -------------- next part -------------- An HTML attachment was scrubbed... URL: From andrew.thaddeus at gmail.com Mon Feb 17 13:00:21 2020 From: andrew.thaddeus at gmail.com (Andrew Martin) Date: Mon, 17 Feb 2020 08:00:21 -0500 Subject: [core libraries] Rename NonEmpty.groupWith/sortWIth to *On* In-Reply-To: References: Message-ID: Philip, Here is the documentation for Generalized List Comprehensions that mentions sortWith: https://downloads.haskell.org/ghc/latest/docs/html/users_guide/glasgow_exts.html#generalised-sql-like-list-comprehensions The asymmetry between Data.List and Data.List.NonEmpty is unfortunate. I think my preference would be a non-breaking change where groupOn is added to Data.List.NonEmpty effectively as an alias for groupWith and they would both stay forever. I've not looked at the semantic difference between sortWith and sortOn, so I'm not sure which of those should be implemented with the other, but ideally, I would like to see both of them there. On Sat, Feb 15, 2020 at 1:59 PM Philip Hazelden wrote: > Hi, > > On Sat, Feb 15, 2020 at 1:00 PM Carter Schonwald < > carter.schonwald at gmail.com> wrote: > >> Pedantic point : when you say semantics, it might be less confusing and >> more precise to performance tradeoffs. >> > > Apologies, but I'm not sure what you mean here. Could you rephrase? > > >> My English language and naive preference is to assume *With functions >> grammar better. Or *by. I think the *on idiom is younger relatively. >> > > I don't personally have an a particular preference between *With and *On, > just a preference for consistency. My proposal isn't motivated by the > english meanings of the words "with" and "on", just by (my perception of) > their current usage in the ecosystem. If *With was used in most places, and > *On was used in Data.List.NonEmpty, then I'd recommend switching NonEmpty > to *With. > > (*By is already taken: `sortBy`, `nubBy`, `groupBy` and so on. That does > seem to be already consistent.) > > An advantage of *On is that it reflects how the functions can be defined > using the `on` function: > > sortOn f = sortBy (compare `on` f) > groupOn f = groupBy ((==) `on` f) > > Historically, it does look like *With has been in use longer. (It looks > like `sortOn` has been in base since 4.8 (2015), and in the "extra" package > since the very first version 0.1 in 2014. `sortWith` has been in GHC.Exts > since at least base 4.0 in 2009.) > > But again, neither of those points factors into my motivation here. > > >> Can I challenge you to reflect on what challenge you are trying to >> address with this proposal and if there’s a course of action that you feel >> improves everything but breaks no code ? >> > > I suppose that simply adding the new names, marking the old ones as > deprecated, and then never actually removing the old ones, would work for > that. > > >> And what would make the change an improvement for software using these >> modules already >> > > Well, a small one is that it would make that software slightly easier to > read for people who recognize the *On convention but not the *With one. > There's also a chance it would make a small number of people notice that > they were using a function that had different semantics from what they > thought, catching bugs that hadn't previously surfaced. > > But I don't think there's any version of this proposal that would > accomplish this in any significant way. Improving existing software isn't > really the point. > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -- -Andrew Thaddeus Martin -------------- next part -------------- An HTML attachment was scrubbed... URL: From dominic at steinitz.org Mon Feb 17 13:12:55 2020 From: dominic at steinitz.org (dominic at steinitz.org) Date: Mon, 17 Feb 2020 13:12:55 +0000 Subject: Replace Random Message-ID: Hello libraries, Following a great blog [post] by @lehins, a group of us (@curiousleo, @lehins and me) are trying to improve the situation with the `random' library. @curiousleo and I have created a [resource] that tests the quality of Haskell random number generators via well known (and not so well known) test suites: dieharder, TestU01, PractRand and gjrand. The current `random' does not fare well especially with the use of the `split' function (but this is well known and the [reason] why `QuickCheck' moved from using it in [2.8] to using [tf-random] in [2.9] and latterly [splitmix] in [2.13]): see [this] for example. On the other hand, `splitmix' [passes] bigcrush[1]. The putative proposal is to replace the current algorithm in `random' with that of `splitmix'[2] and to remove the performance bottleneck by changing the interface (the current interface causes the performance infelicity by making "all of the integral numbers go through the arbitrary precision Integer in order to produce the value in a desired range") - see @lehin's blog for more details. Can anyone interested: * Create a separate issue for each concern they have (eg. range for floats (0, 1] vs [0, 1], etc.) [here]. * Submit PRs with target at the [interface-to-performance] branch (or into master if it is vastly different approach) with your suggested alternatives. If you are going to raise a concern then it might be worth reading some of the [discussions] that have already taken place. We think once we have the API flashed out, switching to splitmix will be a piece of cake and will require an addition of just a few lines of code and removal of current StdGen related functionality. For historical reasons instead of removing it we could move StdGen into a separate module with a disclaimer not to use it, but that isn't terribly important. The Random Team (@lehins, @curiousleo, @idontgetoutmuch) [post] https://alexey.kuleshevi.ch/blog/2019/12/21/random-benchmarks/ [resource] https://github.com/tweag/random-quality [reason] http://publications.lib.chalmers.se/records/fulltext/183348/local_183348.pdf [2.8] https://hackage.haskell.org/package/QuickCheck-2.8 [tf-random] https://hackage.haskell.org/package/tf-random [2.9] https://hackage.haskell.org/package/QuickCheck-2.9 [splitmix] https://hackage.haskell.org/package/splitmix [2.13] https://hackage.haskell.org/package/QuickCheck-2.13 [this] https://github.com/tweag/random-quality/blob/master/results/random-word32-split-practrand-1gb [passes] https://github.com/tweag/random-quality/blob/master/results/splitmix-word32-testu01-bigcrush [here] https://github.com/idontgetoutmuch/random/issues [interface-to-performance] https://github.com/idontgetoutmuch/random/tree/interface-to-performance [discussions] https://github.com/idontgetoutmuch/random/pull/1 Footnotes _________ [1] Just to clarify: both random and splitmix pass BigCrush. random fails any statistical test immediately (e.g. [SmallCrush] (https://github.com/tweag/random-quality/blob/master/results/random-word32-split-testu01-smallcrush#L337-L349) and other even smaller ones) when a sequence based on split is used. splitmix passes Crush when split is part of the sequence, but I've seen it fail one test in BigCrush ("LinearComp"). So we should just be careful here: splitmix itself passes BigCrush and split-based sequences all pass Crush, but not all pass BigCrush. [2] `split' is already availaible as an instance: `instance Random SMGen where'. From carter.schonwald at gmail.com Mon Feb 17 15:58:51 2020 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Mon, 17 Feb 2020 10:58:51 -0500 Subject: [core libraries] Rename NonEmpty.groupWith/sortWIth to *On* In-Reply-To: References: Message-ID: It seems like the *on family in general has a nontrivial increase in space usage and the only differences have to do with application specific time vs memory tradeoffs that need to measured at the application level. I’m totally for improved consistency. But I’m not sure what consistency there is to aim for here. On Mon, Feb 17, 2020 at 8:00 AM Andrew Martin wrote: > Philip, > > Here is the documentation for Generalized List Comprehensions that > mentions sortWith: > https://downloads.haskell.org/ghc/latest/docs/html/users_guide/glasgow_exts.html#generalised-sql-like-list-comprehensions > > The asymmetry between Data.List and Data.List.NonEmpty is unfortunate. I > think my preference would be a non-breaking change where groupOn is added > to Data.List.NonEmpty effectively as an alias for groupWith and they would > both stay forever. I've not looked at the semantic difference between > sortWith and sortOn, so I'm not sure which of those should be implemented > with the other, but ideally, I would like to see both of them there. > > On Sat, Feb 15, 2020 at 1:59 PM Philip Hazelden > wrote: > >> Hi, >> >> On Sat, Feb 15, 2020 at 1:00 PM Carter Schonwald < >> carter.schonwald at gmail.com> wrote: >> >>> Pedantic point : when you say semantics, it might be less confusing and >>> more precise to performance tradeoffs. >>> >> >> Apologies, but I'm not sure what you mean here. Could you rephrase? >> >> >>> My English language and naive preference is to assume *With functions >>> grammar better. Or *by. I think the *on idiom is younger relatively. >>> >> >> I don't personally have an a particular preference between *With and *On, >> just a preference for consistency. My proposal isn't motivated by the >> english meanings of the words "with" and "on", just by (my perception of) >> their current usage in the ecosystem. If *With was used in most places, and >> *On was used in Data.List.NonEmpty, then I'd recommend switching NonEmpty >> to *With. >> >> (*By is already taken: `sortBy`, `nubBy`, `groupBy` and so on. That does >> seem to be already consistent.) >> >> An advantage of *On is that it reflects how the functions can be defined >> using the `on` function: >> >> sortOn f = sortBy (compare `on` f) >> groupOn f = groupBy ((==) `on` f) >> >> Historically, it does look like *With has been in use longer. (It looks >> like `sortOn` has been in base since 4.8 (2015), and in the "extra" package >> since the very first version 0.1 in 2014. `sortWith` has been in GHC.Exts >> since at least base 4.0 in 2009.) >> >> But again, neither of those points factors into my motivation here. >> >> >>> Can I challenge you to reflect on what challenge you are trying to >>> address with this proposal and if there’s a course of action that you feel >>> improves everything but breaks no code ? >>> >> >> I suppose that simply adding the new names, marking the old ones as >> deprecated, and then never actually removing the old ones, would work for >> that. >> >> >>> And what would make the change an improvement for software using these >>> modules already >>> >> >> Well, a small one is that it would make that software slightly easier to >> read for people who recognize the *On convention but not the *With one. >> There's also a chance it would make a small number of people notice that >> they were using a function that had different semantics from what they >> thought, catching bugs that hadn't previously surfaced. >> >> But I don't think there's any version of this proposal that would >> accomplish this in any significant way. Improving existing software isn't >> really the point. >> > _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > >> > > -- > -Andrew Thaddeus Martin > -------------- next part -------------- An HTML attachment was scrubbed... URL: From carter.schonwald at gmail.com Mon Feb 17 16:05:16 2020 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Mon, 17 Feb 2020 11:05:16 -0500 Subject: Fix Random In-Reply-To: References: Message-ID: Yup. I have some of these changes in a branch for a while. Just was uncertain that those who share the common interface are ok with the current tyoeclass interface breaking. Sounds like everyone’s willing to deal with the needed breakage. I’ll have a release candidate to share publicly in a few weeks. Meta point: Dominic if you want to communicate with me try email. You seem to prefer anything but direct concrete communication with me. OTOH I guess we just are terrible at communicating with each other. And I guess that’s fine. Just unfortunate. On Mon, Feb 17, 2020 at 8:13 AM wrote: > Hello libraries, > > Following a great blog [post] by @lehins, a group of us (@curiousleo, > @lehins and me) are trying to improve the situation with the `random' > library. > > @curiousleo and I have created a [resource] that tests the quality of > Haskell random number generators via well known (and not so well known) > test suites: dieharder, TestU01, PractRand and gjrand. The current > `random' does not fare well especially with the use of the `split' > function (but this is well known and the [reason] why `QuickCheck' moved > from using it in [2.8] to using [tf-random] in [2.9] and latterly > [splitmix] in [2.13]): see [this] for example. On the other hand, > `splitmix' [passes] bigcrush[1]. > > The putative proposal is to replace the current algorithm in `random' > with that of `splitmix'[2] and to remove the performance bottleneck by > changing the interface (the current interface causes the performance > infelicity by making "all of the integral numbers go through the > arbitrary precision Integer in order to produce the value in a desired > range") - see @lehin's blog for more details. > > Can anyone interested: > > * Create a separate issue for each concern they have (eg. range for > floats (0, 1] vs [0, 1], etc.) [here]. > * Submit PRs with target at the [interface-to-performance] branch (or > into master if it is vastly different approach) with your suggested > alternatives. > > If you are going to raise a concern then it might be worth reading some > of the [discussions] that have already taken place. > > We think once we have the API flashed out, switching to splitmix will be > a piece of cake and will require an addition of just a few lines of code > and removal of current StdGen related functionality. For historical > reasons instead of removing it we could move StdGen into a separate > module with a disclaimer not to use it, but that isn't terribly > important. > > The Random Team (@lehins, @curiousleo, @idontgetoutmuch) > > > [post] https://alexey.kuleshevi.ch/blog/2019/12/21/random-benchmarks/ > > [resource] https://github.com/tweag/random-quality > > [reason] > > http://publications.lib.chalmers.se/records/fulltext/183348/local_183348.pdf > > [2.8] https://hackage.haskell.org/package/QuickCheck-2.8 > > [tf-random] https://hackage.haskell.org/package/tf-random > > [2.9] https://hackage.haskell.org/package/QuickCheck-2.9 > > [splitmix] https://hackage.haskell.org/package/splitmix > > [2.13] https://hackage.haskell.org/package/QuickCheck-2.13 > > [this] > > https://github.com/tweag/random-quality/blob/master/results/random-word32-split-practrand-1gb > > [passes] > > https://github.com/tweag/random-quality/blob/master/results/splitmix-word32-testu01-bigcrush > > [here] https://github.com/idontgetoutmuch/random/issues > > [interface-to-performance] > https://github.com/idontgetoutmuch/random/tree/interface-to-performance > > [discussions] https://github.com/idontgetoutmuch/random/pull/1 > > > > Footnotes > _________ > > [1] Just to clarify: both random and splitmix pass BigCrush. random > fails any statistical test immediately (e.g. [SmallCrush] > ( > https://github.com/tweag/random-quality/blob/master/results/random-word32-split-testu01-smallcrush#L337-L349 > ) > and other even smaller ones) when a sequence based on split is > used. splitmix passes Crush when split is part of the sequence, but > I've seen it fail one test in BigCrush ("LinearComp"). So we should > just be careful here: splitmix itself passes BigCrush and split-based > sequences all pass Crush, but not all pass BigCrush. > > [2] `split' is already availaible as an instance: `instance Random > SMGen where'. > > _______________________________________________ > 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 carter.schonwald at gmail.com Mon Feb 17 16:29:16 2020 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Mon, 17 Feb 2020 11:29:16 -0500 Subject: Fix Random In-Reply-To: References: Message-ID: Thx for the kick start. Was taking some downtime and personal/work projects as my focus and break after releasing the new vector last month. Random is on the top of my oss queue atm On Mon, Feb 17, 2020 at 11:05 AM Carter Schonwald < carter.schonwald at gmail.com> wrote: > Yup. I have some of these changes in a branch for a while. Just was > uncertain that those who share the common interface are ok with the current > tyoeclass interface breaking. > > Sounds like everyone’s willing to deal with the needed breakage. > > I’ll have a release candidate to share publicly in a few weeks. > > > Meta point: Dominic if you want to communicate with me try email. You seem > to prefer anything but direct concrete communication with me. OTOH I guess > we just are terrible at communicating with each other. And I guess that’s > fine. Just unfortunate. > > > On Mon, Feb 17, 2020 at 8:13 AM wrote: > >> Hello libraries, >> >> Following a great blog [post] by @lehins, a group of us (@curiousleo, >> @lehins and me) are trying to improve the situation with the `random' >> library. >> >> @curiousleo and I have created a [resource] that tests the quality of >> Haskell random number generators via well known (and not so well known) >> test suites: dieharder, TestU01, PractRand and gjrand. The current >> `random' does not fare well especially with the use of the `split' >> function (but this is well known and the [reason] why `QuickCheck' moved >> from using it in [2.8] to using [tf-random] in [2.9] and latterly >> [splitmix] in [2.13]): see [this] for example. On the other hand, >> `splitmix' [passes] bigcrush[1]. >> >> The putative proposal is to replace the current algorithm in `random' >> with that of `splitmix'[2] and to remove the performance bottleneck by >> changing the interface (the current interface causes the performance >> infelicity by making "all of the integral numbers go through the >> arbitrary precision Integer in order to produce the value in a desired >> range") - see @lehin's blog for more details. >> >> Can anyone interested: >> >> * Create a separate issue for each concern they have (eg. range for >> floats (0, 1] vs [0, 1], etc.) [here]. >> * Submit PRs with target at the [interface-to-performance] branch (or >> into master if it is vastly different approach) with your suggested >> alternatives. >> >> If you are going to raise a concern then it might be worth reading some >> of the [discussions] that have already taken place. >> >> We think once we have the API flashed out, switching to splitmix will be >> a piece of cake and will require an addition of just a few lines of code >> and removal of current StdGen related functionality. For historical >> reasons instead of removing it we could move StdGen into a separate >> module with a disclaimer not to use it, but that isn't terribly >> important. >> >> The Random Team (@lehins, @curiousleo, @idontgetoutmuch) >> >> >> [post] https://alexey.kuleshevi.ch/blog/2019/12/21/random-benchmarks/ >> >> [resource] https://github.com/tweag/random-quality >> >> [reason] >> >> http://publications.lib.chalmers.se/records/fulltext/183348/local_183348.pdf >> >> [2.8] https://hackage.haskell.org/package/QuickCheck-2.8 >> >> [tf-random] https://hackage.haskell.org/package/tf-random >> >> [2.9] https://hackage.haskell.org/package/QuickCheck-2.9 >> >> [splitmix] https://hackage.haskell.org/package/splitmix >> >> [2.13] https://hackage.haskell.org/package/QuickCheck-2.13 >> >> [this] >> >> https://github.com/tweag/random-quality/blob/master/results/random-word32-split-practrand-1gb >> >> [passes] >> >> https://github.com/tweag/random-quality/blob/master/results/splitmix-word32-testu01-bigcrush >> >> [here] https://github.com/idontgetoutmuch/random/issues >> >> [interface-to-performance] >> https://github.com/idontgetoutmuch/random/tree/interface-to-performance >> >> [discussions] https://github.com/idontgetoutmuch/random/pull/1 >> >> >> >> Footnotes >> _________ >> >> [1] Just to clarify: both random and splitmix pass BigCrush. random >> fails any statistical test immediately (e.g. [SmallCrush] >> ( >> https://github.com/tweag/random-quality/blob/master/results/random-word32-split-testu01-smallcrush#L337-L349 >> ) >> and other even smaller ones) when a sequence based on split is >> used. splitmix passes Crush when split is part of the sequence, but >> I've seen it fail one test in BigCrush ("LinearComp"). So we should >> just be careful here: splitmix itself passes BigCrush and split-based >> sequences all pass Crush, but not all pass BigCrush. >> >> [2] `split' is already availaible as an instance: `instance Random >> SMGen where'. >> >> _______________________________________________ >> 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 philip.hazelden at gmail.com Mon Feb 17 22:39:54 2020 From: philip.hazelden at gmail.com (Philip Hazelden) Date: Mon, 17 Feb 2020 22:39:54 +0000 Subject: [core libraries] Rename NonEmpty.groupWith/sortWIth to *On* In-Reply-To: References: Message-ID: (Sending again with reply all...) On Mon, Feb 17, 2020 at 1:00 PM Andrew Martin wrote: > Here is the documentation for Generalized List Comprehensions that mentions sortWith: https://downloads.haskell.org/ghc/latest/docs/html/users_guide/glasgow_exts.html#generalised-sql-like-list-comprehensions Yes, it mentions sortWith and groupWith. But these functions only seem to be used explicitly, by name. The rationale given for the *With names in NonEmpty was that using that extension and RebindableSyntax, the names could be used implicitly. In that case it would be more awkward to use functions named sortOn or groupOn. But as far as I can tell, that doesn't happen. (I assume it either did at the time, or was expected to in the near future.) > The asymmetry between Data.List and Data.List.NonEmpty is unfortunate. I think my preference would be a non-breaking change where groupOn is added to Data.List.NonEmpty effectively as an alias for groupWith and they would both stay forever. I've not looked at the semantic difference between sortWith and sortOn, so I'm not sure which of those should be implemented with the other, but ideally, I would like to see both of them there. I do think adding the new names and not removing the others would be an improvement on the status quo, though it's not my preference. -------------- next part -------------- An HTML attachment was scrubbed... URL: From philip.hazelden at gmail.com Mon Feb 17 23:26:55 2020 From: philip.hazelden at gmail.com (Philip Hazelden) Date: Mon, 17 Feb 2020 23:26:55 +0000 Subject: [core libraries] Rename NonEmpty.groupWith/sortWIth to *On* In-Reply-To: References: Message-ID: On Mon, Feb 17, 2020 at 3:59 PM Carter Schonwald wrote: > It seems like the *on family in general has a nontrivial increase in space > usage and the only differences have to do with application specific time vs > memory tradeoffs that need to measured at the application level. > To be clear, this particular tradeoff isn't relevant for every *On function. Of the ones under discussion, it applies to sortWith, groupAllWith and groupAllWith1, but not groupWith or groupWith1. Some things I think are worth noting: * There must be lots of common functions that could choose different implementation tradeoffs, but we don't keep multiple versions of them around. * The existing performance differences aren't documented. (Data.List.sortOn tells us that it only evaluates `f` once per element, but it doesn't tell us about the costs; the others don't mention performance at all.) I predict very few people currently choose between GHC.Exts.sortWith and Data.List.sortOn according to their performance needs. * The Data.List.sortOn implementation is somewhat subtle and complicated. The NonEmpty.sortWith implementation is literally `sortBy . comparing` and GHC.Exts.sortWith isn't much more complicated. (`sortWith f = sortBy (\x y -> compare (f x) (f y))`; I don't know if there are reasons to prefer or disprefer this compared to `sortBy . comparing`.) If someone wants this behavior, it's not hard for them to get. Based on these, I don't think there's much value in deliberately[1] making sure both implementations have a name, which is why I proposed to replace `sortWith` with `sortOn` instead of keeping them both around. [1] Of course, there's value in not changing things once they're there. By "deliberately", I mean that if we weren't already in this situation, and someone proposed adding a separate function that was semantically equivalent to `sortOn` but implemented as `sortBy . comparing`, I don't think that would see much support. -------------- next part -------------- An HTML attachment was scrubbed... URL: From b at chreekat.net Tue Feb 18 07:45:04 2020 From: b at chreekat.net (Bryan Richter) Date: Tue, 18 Feb 2020 09:45:04 +0200 Subject: [core libraries] Rename NonEmpty.groupWith/sortWIth to *On* In-Reply-To: References: Message-ID: Adding to Philip's "things worth noting": I think anyone sophisticated enough (and lucky enough) to have their most important performance bottleneck localized to a call to sortOn instead of sortWith (or vice versa) are also sophisticated enough to implement their own version when necessary. Consistent names, on the other hand, are useful to everyone, all the time. I don't think what I just said is a surprising insight for anyone, but I thought it would be useful to state it explicitly. :) -Bryan P.s. +1 to documenting performance differences, for those rare moments they matter. On Tue, 18 Feb 2020, 1.27 Philip Hazelden, wrote: > On Mon, Feb 17, 2020 at 3:59 PM Carter Schonwald < > carter.schonwald at gmail.com> wrote: > >> It seems like the *on family in general has a nontrivial increase in >> space usage and the only differences have to do with application specific >> time vs memory tradeoffs that need to measured at the application level. >> > > To be clear, this particular tradeoff isn't relevant for every *On > function. Of the ones under discussion, it applies to sortWith, > groupAllWith and groupAllWith1, but not groupWith or groupWith1. > > Some things I think are worth noting: > > * There must be lots of common functions that could choose different > implementation tradeoffs, but we don't keep multiple versions of them > around. > * The existing performance differences aren't documented. > (Data.List.sortOn tells us that it only evaluates `f` once per element, but > it doesn't tell us about the costs; the others don't mention performance at > all.) I predict very few people currently choose between GHC.Exts.sortWith > and Data.List.sortOn according to their performance needs. > * The Data.List.sortOn implementation is somewhat subtle and complicated. > The NonEmpty.sortWith implementation is literally `sortBy . comparing` and > GHC.Exts.sortWith isn't much more complicated. (`sortWith f = sortBy (\x y > -> compare (f x) (f y))`; I don't know if there are reasons to prefer or > disprefer this compared to `sortBy . comparing`.) If someone wants this > behavior, it's not hard for them to get. > > Based on these, I don't think there's much value in deliberately[1] making > sure both implementations have a name, which is why I proposed to replace > `sortWith` with `sortOn` instead of keeping them both around. > > [1] Of course, there's value in not changing things once they're there. By > "deliberately", I mean that if we weren't already in this situation, and > someone proposed adding a separate function that was semantically > equivalent to `sortOn` but implemented as `sortBy . comparing`, I don't > think that would see much support. > _______________________________________________ > 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 dominic at steinitz.org Tue Feb 18 11:50:51 2020 From: dominic at steinitz.org (dominic at steinitz.org) Date: Tue, 18 Feb 2020 11:50:51 +0000 Subject: Fix Random In-Reply-To: References: Message-ID: Hi Carter, That’s great :) May I suggest you make a PR of your proposal against https://github.com/idontgetoutmuch/random/tree/master as that is the latest release on Hackage. That way everyone will be able to see what the changes are against the latest release. The proposal @lehins, @curiousleo and I have been working on are here: * https://github.com/idontgetoutmuch/random/pull/1 * https://github.com/idontgetoutmuch/random/pull/2 An alternative would be to create a branch from v1.1 tag and then we could all submit PRs against that branch. Dominic Steinitz dominic at steinitz.org http://idontgetoutmuch.org Twitter: @idontgetoutmuch > On 17 Feb 2020, at 16:05, Carter Schonwald wrote: > > Yup. I have some of these changes in a branch for a while. Just was uncertain that those who share the common interface are ok with the current tyoeclass interface breaking. > > Sounds like everyone’s willing to deal with the needed breakage. > > I’ll have a release candidate to share publicly in a few weeks. -------------- next part -------------- An HTML attachment was scrubbed... URL: From carter.schonwald at gmail.com Sat Feb 22 20:45:52 2020 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Sat, 22 Feb 2020 15:45:52 -0500 Subject: =?UTF-8?Q?Is_a_a_way_to_do_a_=E2=80=9CBare=E2=80=9D_state_monad_in_modern_?= =?UTF-8?Q?Haskell=3F?= Message-ID: 1) we have a monad instance for (r -> ) 2) is there some way we can arrange sans newtype an instance for its state monad sibling ( /\ x . s-> (s,x)) without a type lambda or some new type or injective type families? I can definitely see that this is def not possible with h98-h2010, is this otherwise expressible? Mostly just curious if there’s some trick that’s now possible :) -------------- next part -------------- An HTML attachment was scrubbed... URL: From lemming at henning-thielemann.de Sat Feb 22 20:52:31 2020 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Sat, 22 Feb 2020 21:52:31 +0100 (CET) Subject: =?UTF-8?Q?Re=3A_Is_a_a_way_to_do_a_=E2=80=9CBare=E2=80=9D_state_monad_in_modern_Haskell=3F?= In-Reply-To: References: Message-ID: On Sat, 22 Feb 2020, Carter Schonwald wrote: > 1) we have a monad instance for (r -> ) And a duplicate Writer monad for (,) w. > 2) is there some way we can arrange sans newtype an instance for its > state monad sibling ( /\ x . s-> (s,x)) without a type lambda or some > new type or injective type families?  I can definitely see that this is > def not possible with h98-h2010, is this otherwise expressible? Why should one want this? From zemyla at gmail.com Mon Feb 24 14:45:54 2020 From: zemyla at gmail.com (Zemyla) Date: Mon, 24 Feb 2020 08:45:54 -0600 Subject: Improved interface to UArray Message-ID: It's currently hard to describe that a type should be usable with UArray or IOUArray, and almost impossible to describe without QualifiedConstraints that it should be usable with STUArray. And it's actually impossible to use GeneralizedNewtypeDeriving to derive new instances of IArray or MArray. It also means that it's difficult to keep the three sets of instances in sync. Therefore, there should be (taking inspiration from primitive) a class that describes types which can be used in unboxed arrays. It'd be something along the lines of: class Unboxed e where unsafeNewUArray :: Int# -> e -> State# s -> (# State# s, MutableByteArray# s #) unsafeNewUArray_ :: Const (Int# -> State# s -> (# State# s, MutableByteArray# s #)) e unsafeReadUArray :: MutableByteArray# s -> Int# -> State# s -> (# State# s, e #) unsafeWriteUArray :: MutableByteArray# s -> Int# -> e -> State# s -> State# s unsafeIndexUArray :: ByteArray# -> Int# -> e And then the instances for UArray, STUArray, and IOUArray would be: instance Unboxed e => IArray UArray e where ... instance Unboxed e => MArray IOUArray e IO where ... instance Unboxed e => MArray (STUArray s) e (ST s) where ... Incidentally, this also means it'd be less effort to add instances like Unboxed CInt, Unboxed a => Unboxed (Complex a), and Unboxed Ordering. -------------- next part -------------- An HTML attachment was scrubbed... URL: From carter.schonwald at gmail.com Fri Feb 28 02:53:54 2020 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Thu, 27 Feb 2020 21:53:54 -0500 Subject: What do you assume when you see fromListN in a library? Message-ID: Hey everyone: When you see fromListN as a function in a library, do you assume / presume it’s expecting an exactly N element list ? Or do you expect/tolerate other behavior ? Should it reject shorter lists? Should it truncate or reject longer lists? A corner case of this came up in some bug discussion I was having regarding vector, and I shall claim and or presume that most folks assume exact size with prompt rejection of too long or too short. Thoughts please ? -Carter -------------- next part -------------- An HTML attachment was scrubbed... URL: From chessai1996 at gmail.com Fri Feb 28 03:30:56 2020 From: chessai1996 at gmail.com (chessai .) Date: Thu, 27 Feb 2020 19:30:56 -0800 Subject: What do you assume when you see fromListN in a library? In-Reply-To: References: Message-ID: I expect a list with precisely length N, and reject anything else. IIRC both primitive and vector do this On Thu, Feb 27, 2020, 6:54 PM Carter Schonwald wrote: > Hey everyone: > When you see fromListN as a function in a library, do you assume / presume > it’s expecting an exactly N element list ? Or do you expect/tolerate other > behavior ? > > Should it reject shorter lists? > > Should it truncate or reject longer lists? > > A corner case of this came up in some bug discussion I was having > regarding vector, and I shall claim and or presume that most folks assume > exact size with prompt rejection of too long or too short. > > Thoughts please ? > > -Carter > _______________________________________________ > 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 zemyla at gmail.com Fri Feb 28 03:40:23 2020 From: zemyla at gmail.com (Zemyla) Date: Thu, 27 Feb 2020 21:40:23 -0600 Subject: What do you assume when you see fromListN in a library? In-Reply-To: References: Message-ID: I'm kind of the opposite. I think the number given to fromListN should be a "size hint", not a redundant coding of the size of the list given. On Thu, Feb 27, 2020, 21:31 chessai . wrote: > I expect a list with precisely length N, and reject anything else. IIRC > both primitive and vector do this > > On Thu, Feb 27, 2020, 6:54 PM Carter Schonwald > wrote: > >> Hey everyone: >> When you see fromListN as a function in a library, do you assume / >> presume it’s expecting an exactly N element list ? Or do you >> expect/tolerate other behavior ? >> >> Should it reject shorter lists? >> >> Should it truncate or reject longer lists? >> >> A corner case of this came up in some bug discussion I was having >> regarding vector, and I shall claim and or presume that most folks assume >> exact size with prompt rejection of too long or too short. >> >> Thoughts please ? >> >> -Carter >> _______________________________________________ >> 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 chessai1996 at gmail.com Fri Feb 28 04:05:55 2020 From: chessai1996 at gmail.com (chessai .) Date: Thu, 27 Feb 2020 20:05:55 -0800 Subject: What do you assume when you see fromListN in a library? In-Reply-To: References: Message-ID: Reading the OverloadedLists wiki seems to agree with Zemlya. It's not unreasonable at all to treat it as a hint IMO, but we should definitely be consistent, since again, primitive treats any length other than the hint as an error. On Thu, Feb 27, 2020, 7:40 PM Zemyla wrote: > I'm kind of the opposite. I think the number given to fromListN should be > a "size hint", not a redundant coding of the size of the list given. > > On Thu, Feb 27, 2020, 21:31 chessai . wrote: > >> I expect a list with precisely length N, and reject anything else. IIRC >> both primitive and vector do this >> >> On Thu, Feb 27, 2020, 6:54 PM Carter Schonwald < >> carter.schonwald at gmail.com> wrote: >> >>> Hey everyone: >>> When you see fromListN as a function in a library, do you assume / >>> presume it’s expecting an exactly N element list ? Or do you >>> expect/tolerate other behavior ? >>> >>> Should it reject shorter lists? >>> >>> Should it truncate or reject longer lists? >>> >>> A corner case of this came up in some bug discussion I was having >>> regarding vector, and I shall claim and or presume that most folks assume >>> exact size with prompt rejection of too long or too short. >>> >>> Thoughts please ? >>> >>> -Carter >>> _______________________________________________ >>> 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 0xd34df00d at gmail.com Fri Feb 28 04:56:50 2020 From: 0xd34df00d at gmail.com (Georg Rudoy) Date: Thu, 27 Feb 2020 23:56:50 -0500 Subject: What do you assume when you see fromListN in a library? In-Reply-To: References: Message-ID: чт, 27 февр. 2020 г. в 21:54, Carter Schonwald : > Should it reject shorter lists? Definitely (although it depends on the definition of "reject" — but I'm even fine with the function being partial there). > Should it truncate or reject longer lists? I'd expect it to "truncate", unless "reject" implies performance benefits (but I couldn't come up with a good example where it does imply those). -- Georg Rudoy From david.feuer at gmail.com Fri Feb 28 05:04:59 2020 From: david.feuer at gmail.com (David Feuer) Date: Fri, 28 Feb 2020 00:04:59 -0500 Subject: What do you assume when you see fromListN in a library? In-Reply-To: References: Message-ID: Trying to deal cleanly with incorrect sizes, treated as hints, could have performance consequences. I'm not sure how bad they'll be. On Thu, Feb 27, 2020, 10:40 PM Zemyla wrote: > I'm kind of the opposite. I think the number given to fromListN should be > a "size hint", not a redundant coding of the size of the list given. > > On Thu, Feb 27, 2020, 21:31 chessai . wrote: > >> I expect a list with precisely length N, and reject anything else. IIRC >> both primitive and vector do this >> >> On Thu, Feb 27, 2020, 6:54 PM Carter Schonwald < >> carter.schonwald at gmail.com> wrote: >> >>> Hey everyone: >>> When you see fromListN as a function in a library, do you assume / >>> presume it’s expecting an exactly N element list ? Or do you >>> expect/tolerate other behavior ? >>> >>> Should it reject shorter lists? >>> >>> Should it truncate or reject longer lists? >>> >>> A corner case of this came up in some bug discussion I was having >>> regarding vector, and I shall claim and or presume that most folks assume >>> exact size with prompt rejection of too long or too short. >>> >>> Thoughts please ? >>> >>> -Carter >>> _______________________________________________ >>> 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 newhoggy at gmail.com Fri Feb 28 05:58:09 2020 From: newhoggy at gmail.com (John Ky) Date: Fri, 28 Feb 2020 16:58:09 +1100 Subject: What do you assume when you see fromListN in a library? In-Reply-To: References: Message-ID: I expect it to pre-allocate space for N elements and populate the vector until there are no more elements or the vector is full and return a vector that has a size the minimum of the length of the input list and N. To me size hint is definitely not what I want because it hides performance/allocation bugs. If it is possible to modify the function type then I would have it return a tuple of a vector with maximum size N as well as the remainder of the list. On Fri, 28 Feb 2020, 2:41 pm Zemyla, wrote: > I'm kind of the opposite. I think the number given to fromListN should be > a "size hint", not a redundant coding of the size of the list given. > > On Thu, Feb 27, 2020, 21:31 chessai . wrote: > >> I expect a list with precisely length N, and reject anything else. IIRC >> both primitive and vector do this >> >> On Thu, Feb 27, 2020, 6:54 PM Carter Schonwald < >> carter.schonwald at gmail.com> wrote: >> >>> Hey everyone: >>> When you see fromListN as a function in a library, do you assume / >>> presume it’s expecting an exactly N element list ? Or do you >>> expect/tolerate other behavior ? >>> >>> Should it reject shorter lists? >>> >>> Should it truncate or reject longer lists? >>> >>> A corner case of this came up in some bug discussion I was having >>> regarding vector, and I shall claim and or presume that most folks assume >>> exact size with prompt rejection of too long or too short. >>> >>> Thoughts please ? >>> >>> -Carter >>> _______________________________________________ >>> 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 andrew.lelechenko at gmail.com Fri Feb 28 10:10:36 2020 From: andrew.lelechenko at gmail.com (Andrew Lelechenko) Date: Fri, 28 Feb 2020 10:10:36 +0000 Subject: What do you assume when you see fromListN in a library? In-Reply-To: References: Message-ID: <78AA5B3F-EA12-41D0-BAB2-39C08A6E4D4A@gmail.com> From the top of my head, I would expect that fromListN rejects both shorter and longer lists. If a user is under a wrong impression that some list has length N, it is better to fail early, before other, more dangerous implications of this impression are made (for example, using `unsafeIndex`). However, my expectations disagree with the documentation, which states that the observable behaviour of fromListN should be equivalent to fromList: http://hackage.haskell.org/package/base-4.12.0.0/docs/GHC-Exts.html#v:fromListN I am not sure what was the motivation behind such choice. Best regards, Andrew > On 28 Feb 2020, at 02:53, Carter Schonwald wrote: > > Hey everyone: > When you see fromListN as a function in a library, do you assume / presume it’s expecting an exactly N element list ? Or do you expect/tolerate other behavior ? > > Should it reject shorter lists? > > Should it truncate or reject longer lists? > > A corner case of this came up in some bug discussion I was having regarding vector, and I shall claim and or presume that most folks assume exact size with prompt rejection of too long or too short. > > Thoughts please ? > > -Carter -------------- next part -------------- An HTML attachment was scrubbed... URL: From zemyla at gmail.com Fri Feb 28 13:38:21 2020 From: zemyla at gmail.com (Zemyla) Date: Fri, 28 Feb 2020 07:38:21 -0600 Subject: What do you assume when you see fromListN in a library? In-Reply-To: <78AA5B3F-EA12-41D0-BAB2-39C08A6E4D4A@gmail.com> References: <78AA5B3F-EA12-41D0-BAB2-39C08A6E4D4A@gmail.com> Message-ID: The motivation is that it would be used with the OverloadedLists extension, and the size would be filled in by the compiler. On Fri, Feb 28, 2020, 04:11 Andrew Lelechenko wrote: > From the top of my head, I would expect that fromListN rejects both > shorter and longer lists. If a user is under a wrong impression that some > list has length N, it is better to fail early, before other, more dangerous > implications of this impression are made (for example, using `unsafeIndex`). > > However, my expectations disagree with the documentation, which states > that the observable behaviour of fromListN should be equivalent to > fromList: > http://hackage.haskell.org/package/base-4.12.0.0/docs/GHC-Exts.html#v:fromListN I > am not sure what was the motivation behind such choice. > > Best regards, > Andrew > > On 28 Feb 2020, at 02:53, Carter Schonwald > wrote: > > Hey everyone: > When you see fromListN as a function in a library, do you assume / presume > it’s expecting an exactly N element list ? Or do you expect/tolerate other > behavior ? > > Should it reject shorter lists? > > Should it truncate or reject longer lists? > > A corner case of this came up in some bug discussion I was having > regarding vector, and I shall claim and or presume that most folks assume > exact size with prompt rejection of too long or too short. > > Thoughts please ? > > -Carter > > > _______________________________________________ > 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 spam at scientician.net Fri Feb 28 15:02:07 2020 From: spam at scientician.net (Bardur Arantsson) Date: Fri, 28 Feb 2020 16:02:07 +0100 Subject: What do you assume when you see fromListN in a library? In-Reply-To: References: Message-ID: On 28/02/2020 04.40, Zemyla wrote: > I'm kind of the opposite. I think the number given to fromListN should > be a "size hint", not a redundant coding of the size of the list given. > One option would be to have a data Size = Hint Int | Exact Int as a parameter and let the user specify desired behavior. (Assuming it's easy to accomodate either.) Regards, From chessai1996 at gmail.com Fri Feb 28 15:10:23 2020 From: chessai1996 at gmail.com (chessai .) Date: Fri, 28 Feb 2020 07:10:23 -0800 Subject: What do you assume when you see fromListN in a library? In-Reply-To: References: Message-ID: I agree with others who have stated that the interpretation as a hint is bad for performance. My intuition has always been that we pre-allocate an array of length N, fill that in with a recursive function while accumulating the length, and rejecting anything incorrect. I think the motivation behind it being a hint is still mostly a mystery to me, until I can find some discussion. I can see how a hint might be useful from the perspective of the desugarer, but for people who are calling fromListN in source code, this seems much less intuitive, if not potentially useful. It might be illuminating if we could find some discussion about why this decision was made, since there might be something more I'm not considering. As it stands, my intuition (and that of most library authors I know, and most libraries I have seen) does not align with that as a hint. E.g. if primitive were to switch to treating N as a hint, it would require a majour version bump, and also it would be a place where a size hint would be most unwelcome because of perf. On Fri, Feb 28, 2020, 7:02 AM Bardur Arantsson wrote: > On 28/02/2020 04.40, Zemyla wrote: > > I'm kind of the opposite. I think the number given to fromListN should > > be a "size hint", not a redundant coding of the size of the list given. > > > > One option would be to have a > > data Size = Hint Int > | Exact Int > > as a parameter and let the user specify desired behavior. (Assuming it's > easy to accomodate either.) > > Regards, > > _______________________________________________ > 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 zemyla at gmail.com Fri Feb 28 17:54:50 2020 From: zemyla at gmail.com (Zemyla) Date: Fri, 28 Feb 2020 11:54:50 -0600 Subject: What do you assume when you see fromListN in a library? In-Reply-To: References: Message-ID: Honestly, we could probably have positive numbers mean "do this number exactly" and negative numbers mean "use this as a hint". For instance: filter p arr = fromListN (negate $ length arr) $ Prelude.filter p $ toList arr This is an increase in definedness, since normally most implementations would error when provided a negative length. On Fri, Feb 28, 2020, 09:11 chessai . wrote: > I agree with others who have stated that the interpretation as a hint is > bad for performance. My intuition has always been that we pre-allocate an > array of length N, fill that in with a recursive function while > accumulating the length, and rejecting anything incorrect. > > I think the motivation behind it being a hint is still mostly a mystery to > me, until I can find some discussion. I can see how a hint might be useful > from the perspective of the desugarer, but for people who are calling > fromListN in source code, this seems much less intuitive, if not > potentially useful. > > It might be illuminating if we could find some discussion about why this > decision was made, since there might be something more I'm not considering. > As it stands, my intuition (and that of most library authors I know, and > most libraries I have seen) does not align with that as a hint. E.g. if > primitive were to switch to treating N as a hint, it would require a majour > version bump, and also it would be a place where a size hint would be most > unwelcome because of perf. > > On Fri, Feb 28, 2020, 7:02 AM Bardur Arantsson > wrote: > >> On 28/02/2020 04.40, Zemyla wrote: >> > I'm kind of the opposite. I think the number given to fromListN should >> > be a "size hint", not a redundant coding of the size of the list given. >> > >> >> One option would be to have a >> >> data Size = Hint Int >> | Exact Int >> >> as a parameter and let the user specify desired behavior. (Assuming it's >> easy to accomodate either.) >> >> Regards, >> >> _______________________________________________ >> 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 oleg.grenrus at iki.fi Fri Feb 28 18:48:41 2020 From: oleg.grenrus at iki.fi (Oleg Grenrus) Date: Fri, 28 Feb 2020 20:48:41 +0200 Subject: What do you assume when you see fromListN in a library? In-Reply-To: References: Message-ID: <0bc97618-eced-4d30-39f4-df581c67804e@iki.fi> My personal expectations may be different based on what the container in question is. Elsewhere in the discussion types in `primitive` and `vector` were mentioned. They are however different. Compare to C++ code snippets, which are all morally `fromList(N)`:     std::array variantA;     for (int i = 0; i < 100; i++) {        primitive[i] = f(i);     }     // not good     std::vector variantB;     for (int i = 0; i < 100; i++) {        primitive.push_back(f(i));     }     std::vector variantC;     variantC.reserve(100);     for (int i = 0; i < 100; i++) {        primitive.push_back(f(i));     } I'm not a fan of changing `fromListN` to be partial function, but if that change is carried on in `vector` there should be a variant which allows to `reserve` without worrying about partiality. - Oleg On 28.2.2020 4.53, Carter Schonwald wrote: > Hey everyone:  > When you see fromListN as a function in a library, do you assume / > presume it’s expecting an exactly N element list ? Or do you > expect/tolerate other behavior ?  > > Should it reject shorter lists? > > Should it truncate or reject longer lists?  > > A corner case of this came up in some bug discussion I was having > regarding vector,  and I shall claim and or presume that most folks > assume exact size with prompt rejection of too long or too short.  > > Thoughts please ? > > -Carter  > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries From david.feuer at gmail.com Fri Feb 28 18:55:37 2020 From: david.feuer at gmail.com (David Feuer) Date: Fri, 28 Feb 2020 13:55:37 -0500 Subject: What do you assume when you see fromListN in a library? In-Reply-To: <0bc97618-eced-4d30-39f4-df581c67804e@iki.fi> References: <0bc97618-eced-4d30-39f4-df581c67804e@iki.fi> Message-ID: There are at least two reasonable sorts of hint: upper bounds and lower bounds. For arrays, either can be useful, but upper bounds are especially nice in combination with resizing primitives (currently only available for SmallArray and ByteArray-backed arrays). For sequences, lower bounds are useful, but upper bounds aren't really. On Fri, Feb 28, 2020, 1:49 PM Oleg Grenrus wrote: > My personal expectations may be different based on what the container in > question is. > Elsewhere in the discussion types in `primitive` and `vector` were > mentioned. > They are however different. > > Compare to C++ code snippets, which are all morally `fromList(N)`: > > std::array variantA; > for (int i = 0; i < 100; i++) { > primitive[i] = f(i); > } > > // not good > std::vector variantB; > for (int i = 0; i < 100; i++) { > primitive.push_back(f(i)); > } > > std::vector variantC; > variantC.reserve(100); > for (int i = 0; i < 100; i++) { > primitive.push_back(f(i)); > } > > I'm not a fan of changing `fromListN` to be partial function, but if > that change is carried on in `vector` there should be a variant which > allows to `reserve` without worrying about partiality. > > - Oleg > > > > On 28.2.2020 4.53, Carter Schonwald wrote: > > Hey everyone: > > When you see fromListN as a function in a library, do you assume / > > presume it’s expecting an exactly N element list ? Or do you > > expect/tolerate other behavior ? > > > > Should it reject shorter lists? > > > > Should it truncate or reject longer lists? > > > > A corner case of this came up in some bug discussion I was having > > regarding vector, and I shall claim and or presume that most folks > > assume exact size with prompt rejection of too long or too short. > > > > Thoughts please ? > > > > -Carter > > > > _______________________________________________ > > 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 emertens at gmail.com Fri Feb 28 19:02:07 2020 From: emertens at gmail.com (Eric Mertens) Date: Fri, 28 Feb 2020 11:02:07 -0800 Subject: What do you assume when you see fromListN in a library? In-Reply-To: References: Message-ID: <590A9E4E-5BC5-44CB-8274-5779DE67F73A@gmail.com> I think we should have the functions exist that make sense to implement. If having a function with a length hint helps perform more efficient allocation of vectors then let's have one. I’d prefer that we simply picked a name that fit the behavior we wanted than picked behavior to fit the name. If it’s unclear what “fromListN” does, then let’s make “fromListWithSizeHint” or “fromListExactN" or something slightly shorter. If we want to avoid partial functions we can take a default element “fromListWithLengthWithDefault” used to pad out the missing elements and then debate what a nice name might be. > On Feb 27, 2020, at 6:53 PM, Carter Schonwald wrote: > > Hey everyone: > When you see fromListN as a function in a library, do you assume / presume it’s expecting an exactly N element list ? Or do you expect/tolerate other behavior ? > > Should it reject shorter lists? > > Should it truncate or reject longer lists? > > A corner case of this came up in some bug discussion I was having regarding vector, and I shall claim and or presume that most folks assume exact size with prompt rejection of too long or too short. > > Thoughts please ? > > -Carter > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries From spam at scientician.net Fri Feb 28 20:01:05 2020 From: spam at scientician.net (Bardur Arantsson) Date: Fri, 28 Feb 2020 21:01:05 +0100 Subject: What do you assume when you see fromListN in a library? In-Reply-To: <0bc97618-eced-4d30-39f4-df581c67804e@iki.fi> References: <0bc97618-eced-4d30-39f4-df581c67804e@iki.fi> Message-ID: On 28/02/2020 19.48, Oleg Grenrus wrote: > >     std::vector variantC; >     variantC.reserve(100); >     for (int i = 0; i < 100; i++) { >        primitive.push_back(f(i)); >     } > > I'm not a fan of changing `fromListN` to be partial function, but if > that change is carried on in `vector` there should be a variant which > allows to `reserve` without worrying about partiality. > > - Oleg > Interestingly, reserve actually is a size hint in the sense of "must be equal or greater than". (According to cppreference.com, anway.) From spam at scientician.net Fri Feb 28 20:03:52 2020 From: spam at scientician.net (Bardur Arantsson) Date: Fri, 28 Feb 2020 21:03:52 +0100 Subject: What do you assume when you see fromListN in a library? In-Reply-To: References: <0bc97618-eced-4d30-39f4-df581c67804e@iki.fi> Message-ID: On 28/02/2020 21.01, Bardur Arantsson wrote: > On 28/02/2020 19.48, Oleg Grenrus wrote: >> >>     std::vector variantC; >>     variantC.reserve(100); >>     for (int i = 0; i < 100; i++) { >>        primitive.push_back(f(i)); >>     } >> >> I'm not a fan of changing `fromListN` to be partial function, but if >> that change is carried on in `vector` there should be a variant which >> allows to `reserve` without worrying about partiality. >> >> - Oleg >> > > Interestingly, reserve actually is a size hint in the sense of "must be > equal or greater than". (Apogies for the self-reply, I fired that one off a bit early.) That said, the expectation in C++ is the you *will* be mutating a vector, so expecting further push_back(), etc. might be reasonable. In 'vector', maybe not so much? Regards, From ekmett at gmail.com Fri Feb 28 21:15:33 2020 From: ekmett at gmail.com (Edward Kmett) Date: Fri, 28 Feb 2020 13:15:33 -0800 Subject: What do you assume when you see fromListN in a library? In-Reply-To: References: Message-ID: I treat any use of a list of length other than N as an error. On Thu, Feb 27, 2020 at 6:54 PM Carter Schonwald wrote: > Hey everyone: > When you see fromListN as a function in a library, do you assume / presume > it’s expecting an exactly N element list ? Or do you expect/tolerate other > behavior ? > > Should it reject shorter lists? > > Should it truncate or reject longer lists? > > A corner case of this came up in some bug discussion I was having > regarding vector, and I shall claim and or presume that most folks assume > exact size with prompt rejection of too long or too short. > > Thoughts please ? > > -Carter > _______________________________________________ > 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 newhoggy at gmail.com Fri Feb 28 22:02:47 2020 From: newhoggy at gmail.com (John Ky) Date: Sat, 29 Feb 2020 09:02:47 +1100 Subject: What do you assume when you see fromListN in a library? In-Reply-To: References: Message-ID: I should add that one of my actual use cases is to take a list of unknown length and chunk it into a list of fixed sized vectors. I use fromListN which allows me to fill a vector up until N and then I move onto the next one etc until the list is exhausted. Requiring an exact N is a pessimisation for me because it would force me to create intermediate lists of the desired size before calling fromListN. I do not mind if a function with the current behaviour exists but with a different name like fromListUntilN or something similar. On Fri, 28 Feb 2020 at 16:58, John Ky wrote: > I expect it to pre-allocate space for N elements and populate the vector > until there are no more elements or the vector is full and return a vector > that has a size the minimum of the length of the input list and N. > > To me size hint is definitely not what I want because it hides > performance/allocation bugs. > > If it is possible to modify the function type then I would have it return > a tuple of a vector with maximum size N as well as the remainder of the > list. > > On Fri, 28 Feb 2020, 2:41 pm Zemyla, wrote: > >> I'm kind of the opposite. I think the number given to fromListN should be >> a "size hint", not a redundant coding of the size of the list given. >> >> On Thu, Feb 27, 2020, 21:31 chessai . wrote: >> >>> I expect a list with precisely length N, and reject anything else. IIRC >>> both primitive and vector do this >>> >>> On Thu, Feb 27, 2020, 6:54 PM Carter Schonwald < >>> carter.schonwald at gmail.com> wrote: >>> >>>> Hey everyone: >>>> When you see fromListN as a function in a library, do you assume / >>>> presume it’s expecting an exactly N element list ? Or do you >>>> expect/tolerate other behavior ? >>>> >>>> Should it reject shorter lists? >>>> >>>> Should it truncate or reject longer lists? >>>> >>>> A corner case of this came up in some bug discussion I was having >>>> regarding vector, and I shall claim and or presume that most folks assume >>>> exact size with prompt rejection of too long or too short. >>>> >>>> Thoughts please ? >>>> >>>> -Carter >>>> _______________________________________________ >>>> 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 carter.schonwald at gmail.com Sat Feb 29 00:34:13 2020 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Fri, 28 Feb 2020 19:34:13 -0500 Subject: Welcome emily and Cale!! Message-ID: Let’s welcome Cale and emily! Before general announce probably good to figure out that voting for chair thing eds stepping down from. @ed: what does chairing clc entail? Also Neil somehow wasn’t on the list before so Ccing him just in case. -Carter From carter.schonwald at gmail.com Sat Feb 29 00:48:18 2020 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Fri, 28 Feb 2020 19:48:18 -0500 Subject: Welcome emily and Cale!! In-Reply-To: References: Message-ID: Derp. Meant to send this to core libraries list ;) But welcome them none the less! -Carter > On Feb 28, 2020, at 7:34 PM, Carter Schonwald wrote: > > Let’s welcome Cale and emily! > > Before general announce probably good to figure out that voting for chair thing eds stepping down from. > > @ed: what does chairing clc entail? > > Also Neil somehow wasn’t on the list before so Ccing him just in case. > -Carter From ekmett at gmail.com Sat Feb 29 03:00:40 2020 From: ekmett at gmail.com (Edward Kmett) Date: Fri, 28 Feb 2020 19:00:40 -0800 Subject: What do you assume when you see fromListN in a library? In-Reply-To: References: Message-ID: Currently the documented behavior of fromListN is undefined when n is not equal to the list length, so you're basically asking for a change in library semantics. I'm rather uncomfortable broadening fromListN's mandate as it is mainly an implementation detail for OverloadedLists that has been hijacked by users for efficiency here and there. Right now it is always valid to define `fromListN _ = fromList`. In a world with these alternate semantics it would not be. Your "fromListUntilN" is a rather complicated beast, because it needs to be able to trim or pad if the list is too short, and take if it is too long, and you still have to handle the drop for chunking. This is asking for way more structure than fromListN which is basically just telling the vector or whatever exactly the final size. It is probably best to try to write the custom combinator that does the right thing maintaining a current mutable vector and trimming or padding the last one, than to burden an optimization for a piece of syntactic sugar with more complex semantics AND completely break the ability to ignore that this optimization exists. -Edward On Fri, Feb 28, 2020 at 2:03 PM John Ky wrote: > I should add that one of my actual use cases is to take a list of unknown > length and chunk it into a list of fixed sized vectors. > > I use fromListN which allows me to fill a vector up until N and then I > move onto the next one etc until the list is exhausted. > > Requiring an exact N is a pessimisation for me because it would force me > to create intermediate lists of the desired size before calling fromListN. > > I do not mind if a function with the current behaviour exists but with a > different name like fromListUntilN or something similar. > > On Fri, 28 Feb 2020 at 16:58, John Ky wrote: > >> I expect it to pre-allocate space for N elements and populate the vector >> until there are no more elements or the vector is full and return a vector >> that has a size the minimum of the length of the input list and N. >> >> To me size hint is definitely not what I want because it hides >> performance/allocation bugs. >> >> If it is possible to modify the function type then I would have it return >> a tuple of a vector with maximum size N as well as the remainder of the >> list. >> >> On Fri, 28 Feb 2020, 2:41 pm Zemyla, wrote: >> >>> I'm kind of the opposite. I think the number given to fromListN should >>> be a "size hint", not a redundant coding of the size of the list given. >>> >>> On Thu, Feb 27, 2020, 21:31 chessai . wrote: >>> >>>> I expect a list with precisely length N, and reject anything else. IIRC >>>> both primitive and vector do this >>>> >>>> On Thu, Feb 27, 2020, 6:54 PM Carter Schonwald < >>>> carter.schonwald at gmail.com> wrote: >>>> >>>>> Hey everyone: >>>>> When you see fromListN as a function in a library, do you assume / >>>>> presume it’s expecting an exactly N element list ? Or do you >>>>> expect/tolerate other behavior ? >>>>> >>>>> Should it reject shorter lists? >>>>> >>>>> Should it truncate or reject longer lists? >>>>> >>>>> A corner case of this came up in some bug discussion I was having >>>>> regarding vector, and I shall claim and or presume that most folks assume >>>>> exact size with prompt rejection of too long or too short. >>>>> >>>>> Thoughts please ? >>>>> >>>>> -Carter >>>>> _______________________________________________ >>>>> 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 >>> >> _______________________________________________ > 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 chessai1996 at gmail.com Sat Feb 29 05:18:01 2020 From: chessai1996 at gmail.com (chessai .) Date: Fri, 28 Feb 2020 21:18:01 -0800 Subject: [core libraries] Rename NonEmpty.groupWith/sortWIth to *On* In-Reply-To: References: Message-ID: I second Andrew's suggestion - add a function alias(es) and then keep the old ones for a long period of time. They're not related to typeclasses or their methods so I don't see the need to keep them forever; anyone with an issue during updating could just resort to `sed`. The compatibility window could be large enough to not disrupt library authors so much, though. Since this is base that window should be fairly large. On Mon, Feb 17, 2020 at 11:45 PM Bryan Richter wrote: > > Adding to Philip's "things worth noting": I think anyone sophisticated enough (and lucky enough) to have their most important performance bottleneck localized to a call to sortOn instead of sortWith (or vice versa) are also sophisticated enough to implement their own version when necessary. > > Consistent names, on the other hand, are useful to everyone, all the time. > > I don't think what I just said is a surprising insight for anyone, but I thought it would be useful to state it explicitly. :) > > -Bryan > > P.s. +1 to documenting performance differences, for those rare moments they matter. > > On Tue, 18 Feb 2020, 1.27 Philip Hazelden, wrote: >> >> On Mon, Feb 17, 2020 at 3:59 PM Carter Schonwald wrote: >>> >>> It seems like the *on family in general has a nontrivial increase in space usage and the only differences have to do with application specific time vs memory tradeoffs that need to measured at the application level. >> >> >> To be clear, this particular tradeoff isn't relevant for every *On function. Of the ones under discussion, it applies to sortWith, groupAllWith and groupAllWith1, but not groupWith or groupWith1. >> >> Some things I think are worth noting: >> >> * There must be lots of common functions that could choose different implementation tradeoffs, but we don't keep multiple versions of them around. >> * The existing performance differences aren't documented. (Data.List.sortOn tells us that it only evaluates `f` once per element, but it doesn't tell us about the costs; the others don't mention performance at all.) I predict very few people currently choose between GHC.Exts.sortWith and Data.List.sortOn according to their performance needs. >> * The Data.List.sortOn implementation is somewhat subtle and complicated. The NonEmpty.sortWith implementation is literally `sortBy . comparing` and GHC.Exts.sortWith isn't much more complicated. (`sortWith f = sortBy (\x y -> compare (f x) (f y))`; I don't know if there are reasons to prefer or disprefer this compared to `sortBy . comparing`.) If someone wants this behavior, it's not hard for them to get. >> >> Based on these, I don't think there's much value in deliberately[1] making sure both implementations have a name, which is why I proposed to replace `sortWith` with `sortOn` instead of keeping them both around. >> >> [1] Of course, there's value in not changing things once they're there. By "deliberately", I mean that if we weren't already in this situation, and someone proposed adding a separate function that was semantically equivalent to `sortOn` but implemented as `sortBy . comparing`, I don't think that would see much support. >> _______________________________________________ >> 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 newhoggy at gmail.com Sat Feb 29 08:14:51 2020 From: newhoggy at gmail.com (John Ky) Date: Sat, 29 Feb 2020 19:14:51 +1100 Subject: What do you assume when you see fromListN in a library? In-Reply-To: References: Message-ID: Oh wow. I only just realised Data.Primitive.Array.fromListN is defined differently to Data.Vector.fromListN. The fromListN function takes the input list's length as a hint. Its behaviour should be equivalent to fromList . The hint can be used to construct the structure l more efficiently compared to fromList . If the given hint does not equal to the input list's length the behaviour of fromListN is not specified. On Sat, 29 Feb 2020 at 14:00, Edward Kmett wrote: > Currently the documented behavior of fromListN is undefined when n is not > equal to the list length, so you're basically asking for a change in > library semantics. I'm rather uncomfortable broadening fromListN's mandate > as it is mainly an implementation detail for OverloadedLists that has been > hijacked by users for efficiency here and there. > > Right now it is always valid to define `fromListN _ = fromList`. In a > world with these alternate semantics it would not be. > > Your "fromListUntilN" is a rather complicated beast, because it needs to > be able to trim or pad if the list is too short, and take if it is too > long, and you still have to handle the drop for chunking. This is asking > for way more structure than fromListN which is basically just telling the > vector or whatever exactly the final size. It is probably best to try to > write the custom combinator that does the right thing maintaining a current > mutable vector and trimming or padding the last one, than to burden an > optimization for a piece of syntactic sugar with more complex semantics AND > completely break the ability to ignore that this optimization exists. > > -Edward > > On Fri, Feb 28, 2020 at 2:03 PM John Ky wrote: > >> I should add that one of my actual use cases is to take a list of unknown >> length and chunk it into a list of fixed sized vectors. >> >> I use fromListN which allows me to fill a vector up until N and then I >> move onto the next one etc until the list is exhausted. >> >> Requiring an exact N is a pessimisation for me because it would force me >> to create intermediate lists of the desired size before calling fromListN. >> >> I do not mind if a function with the current behaviour exists but with a >> different name like fromListUntilN or something similar. >> >> On Fri, 28 Feb 2020 at 16:58, John Ky wrote: >> >>> I expect it to pre-allocate space for N elements and populate the vector >>> until there are no more elements or the vector is full and return a vector >>> that has a size the minimum of the length of the input list and N. >>> >>> To me size hint is definitely not what I want because it hides >>> performance/allocation bugs. >>> >>> If it is possible to modify the function type then I would have it >>> return a tuple of a vector with maximum size N as well as the remainder of >>> the list. >>> >>> On Fri, 28 Feb 2020, 2:41 pm Zemyla, wrote: >>> >>>> I'm kind of the opposite. I think the number given to fromListN should >>>> be a "size hint", not a redundant coding of the size of the list given. >>>> >>>> On Thu, Feb 27, 2020, 21:31 chessai . wrote: >>>> >>>>> I expect a list with precisely length N, and reject anything else. >>>>> IIRC both primitive and vector do this >>>>> >>>>> On Thu, Feb 27, 2020, 6:54 PM Carter Schonwald < >>>>> carter.schonwald at gmail.com> wrote: >>>>> >>>>>> Hey everyone: >>>>>> When you see fromListN as a function in a library, do you assume / >>>>>> presume it’s expecting an exactly N element list ? Or do you >>>>>> expect/tolerate other behavior ? >>>>>> >>>>>> Should it reject shorter lists? >>>>>> >>>>>> Should it truncate or reject longer lists? >>>>>> >>>>>> A corner case of this came up in some bug discussion I was having >>>>>> regarding vector, and I shall claim and or presume that most folks assume >>>>>> exact size with prompt rejection of too long or too short. >>>>>> >>>>>> Thoughts please ? >>>>>> >>>>>> -Carter >>>>>> _______________________________________________ >>>>>> 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 >>>> >>> _______________________________________________ >> 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 Sat Feb 29 08:24:39 2020 From: ekmett at gmail.com (Edward Kmett) Date: Sat, 29 Feb 2020 00:24:39 -0800 Subject: What do you assume when you see fromListN in a library? In-Reply-To: References: Message-ID: Data.Primitive.Array.fromListN is a re-export of base's IsList version, which includes that caveat. Data.Vector exports its own combinator and chooses to provide a stronger rule. It is a perfectly valid definition of `fromListN`, but other instances aren't required to work that way. Vector is the odd library out here. -Edward On Sat, Feb 29, 2020 at 12:15 AM John Ky wrote: > Oh wow. > > I only just realised Data.Primitive.Array.fromListN is defined > differently to Data.Vector.fromListN. > > The fromListN > function > takes the input list's length as a hint. Its behaviour should be equivalent > to fromList > . > The hint can be used to construct the structure l more efficiently > compared to fromList > . > If the given hint does not equal to the input list's length the behaviour > of fromListN > is > not specified. > > > On Sat, 29 Feb 2020 at 14:00, Edward Kmett wrote: > >> Currently the documented behavior of fromListN is undefined when n is not >> equal to the list length, so you're basically asking for a change in >> library semantics. I'm rather uncomfortable broadening fromListN's mandate >> as it is mainly an implementation detail for OverloadedLists that has been >> hijacked by users for efficiency here and there. >> >> Right now it is always valid to define `fromListN _ = fromList`. In a >> world with these alternate semantics it would not be. >> >> Your "fromListUntilN" is a rather complicated beast, because it needs to >> be able to trim or pad if the list is too short, and take if it is too >> long, and you still have to handle the drop for chunking. This is asking >> for way more structure than fromListN which is basically just telling the >> vector or whatever exactly the final size. It is probably best to try to >> write the custom combinator that does the right thing maintaining a current >> mutable vector and trimming or padding the last one, than to burden an >> optimization for a piece of syntactic sugar with more complex semantics AND >> completely break the ability to ignore that this optimization exists. >> >> -Edward >> >> On Fri, Feb 28, 2020 at 2:03 PM John Ky wrote: >> >>> I should add that one of my actual use cases is to take a list of >>> unknown length and chunk it into a list of fixed sized vectors. >>> >>> I use fromListN which allows me to fill a vector up until N and then I >>> move onto the next one etc until the list is exhausted. >>> >>> Requiring an exact N is a pessimisation for me because it would force me >>> to create intermediate lists of the desired size before calling fromListN. >>> >>> I do not mind if a function with the current behaviour exists but with a >>> different name like fromListUntilN or something similar. >>> >>> On Fri, 28 Feb 2020 at 16:58, John Ky wrote: >>> >>>> I expect it to pre-allocate space for N elements and populate the >>>> vector until there are no more elements or the vector is full and return a >>>> vector that has a size the minimum of the length of the input list and N. >>>> >>>> To me size hint is definitely not what I want because it hides >>>> performance/allocation bugs. >>>> >>>> If it is possible to modify the function type then I would have it >>>> return a tuple of a vector with maximum size N as well as the remainder of >>>> the list. >>>> >>>> On Fri, 28 Feb 2020, 2:41 pm Zemyla, wrote: >>>> >>>>> I'm kind of the opposite. I think the number given to fromListN should >>>>> be a "size hint", not a redundant coding of the size of the list given. >>>>> >>>>> On Thu, Feb 27, 2020, 21:31 chessai . wrote: >>>>> >>>>>> I expect a list with precisely length N, and reject anything else. >>>>>> IIRC both primitive and vector do this >>>>>> >>>>>> On Thu, Feb 27, 2020, 6:54 PM Carter Schonwald < >>>>>> carter.schonwald at gmail.com> wrote: >>>>>> >>>>>>> Hey everyone: >>>>>>> When you see fromListN as a function in a library, do you assume / >>>>>>> presume it’s expecting an exactly N element list ? Or do you >>>>>>> expect/tolerate other behavior ? >>>>>>> >>>>>>> Should it reject shorter lists? >>>>>>> >>>>>>> Should it truncate or reject longer lists? >>>>>>> >>>>>>> A corner case of this came up in some bug discussion I was having >>>>>>> regarding vector, and I shall claim and or presume that most folks assume >>>>>>> exact size with prompt rejection of too long or too short. >>>>>>> >>>>>>> Thoughts please ? >>>>>>> >>>>>>> -Carter >>>>>>> _______________________________________________ >>>>>>> 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 >>>>> >>>> _______________________________________________ >>> Libraries mailing list >>> Libraries at haskell.org >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >>> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: