Re: [Haskell-cafe] Proposal: (.:) operator in base.

(Forgot reply all)
---------- Forwarded message ----------
From: "Mike Ledger"
Of course I meant to write ((->) e)
On 17 August 2016 at 22:39:36, Csongor Kiss (kiss.csongor.kiss@gmail.com) wrote:
Can you provide a bit more detail on why you think (fmap . fmap) captures the concept behind (.) . (.) ? It certainly does generalise it in one way - and I do get how, but is it the *right* generalisation?
Or does it just coincide with (-> e)’s fmap being defined as (.), and in fact we would prefer to generalise the composition aspect, in which case Category would be a more ‘obvious’ place to look?
On 17 August 2016 at 22:15:56, Tony Morris (tonymorris@gmail.com) wrote:
You'd generalise it to:
fmap . fmap :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b)
And then, would you do the same for Traversable, Foldable and Applicative?
On 18/08/16 03:43, Alex Belanger wrote:
Hi,
Some of you might be familiar with (.:) = (.) . (.).
It has type :: (c -> d) -> (a -> b -> c) -> a -> b -> d
It allows the composition of two functions, the first one, accepting one operand, and the second, two operands.
This appears to be a very common pattern, referenced a bit everywhere, almost always defined on lambdabot and found in multiple codebases in the wild.
I'd like the know the general sentiment about this operator, as well as how its inclusion in base, probably Data.Function, would be perceived before I actually try to make it happen.
Cheers, Alex (nitrix).
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to:http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
------------------------------ _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 On 18/08/16 23:57, Mike Ledger wrote:
IMO: I've never seen a compelling use of this; I think it decreases clarity, and barely shaves off any characters from equivalent "pointful" expressions.
I think it quite compelling. An example: asSeconds :: Hour h -> Minute m -> Second s -> Second t - -- | asSeconds take some 'TimeUnit's and convert them to 'Second's. asSeconds h m s = MkSecond $ 3600 * timeVal h + 60 * timeVal m + timeVal s hmsToDiffTime :: Hour h -> Minute m -> Second s -> DiffTime - -- | 'hmsToDiffTime' converts time of day in hours, minutes and seconds to the - -- time from midnight as a 'DiffTime'. hmsToDiffTime = (secondsToDiffTime . timeVal) .:. asSeconds As for putting it in base -- meh. I use the composition package, or define it myself. So I agree with Oleg; -1. - -- Alexander alexander@plaimi.net https://secure.plaimi.net/~alexander -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAEBCgAGBQJXtwTXAAoJENQqWdRUGk8BP/UQAIcKzqVRhkVs0qtFDneTpSIi jLPPXMELbMnQe/ZQH2c5SaVM4+eDJIky33FEzrh9FWMeDftz1QFrsC+pPq+5/Esw U3h1HJrAJKl+zZ/bC1GQj9ObWKNROj3jEEt9pyNBcoHpxVnCohD3Y6Gx2LknE7m0 hnFlO0rCZZamk+pSeSlmLkkDM/MNxTx/FQcuZT0omxZtvzrz4cN7a069Gx35C+vr RK6NpiD5NUqTvMCL0zeI2yRpg2GV2PQcwV0CEWjLCsJYMcoeiF8+prSBdwzatgjH 7k1bHUdGwvcRzB74dyxIOPyHBgIDUFzj7bcE+NT0V20WXaz/Jgl73zZaIG9XtW19 aJ+RzW+aBSLEh8+uERc+Al9NpM9dLR94mDWIK/MZWEmlFHo8+W/md27+OxvM5BOr YCRpoQYeYDkepTAyRK2wRlszFXydDze8K6PMAq4DUE7xtUXofEbcodWA0quLxP4N ro2A8E4kqnO6BVD7iN+qch8TxmEiVYpqZnAjNz8eSyQCdn9UORpcMLT8yQ963nml 17yKRjHYDwg/g8EC1UjqJ9KwVFRhqQwdk//IupRyZ/5PPkEChy8t/ZjmmGKfLy0H CfhpRiNi0ozR+bYpUJcOdNM0ckCzgq5++9+M643RGjNWvD4fKDI8idNNn9eLlcom kaABFBC5Gbx2O6/rgpHc =X/Rb -----END PGP SIGNATURE-----

I didn't even know about the composition package. I just wanted it to be
readily available to everyone.
A quick look, `composition` seems really nice and is probably more aligned
with Haskell ecosystem's philosophy of keeping base to what is only stricly
needed by GHC.
These were some valuable feedback. I think I got my answer and we can let
the thread die (:
Much appreciated,
Alex
On Aug 19, 2016 9:08 AM, "Alexander Berntsen"
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512
On 18/08/16 23:57, Mike Ledger wrote:
IMO: I've never seen a compelling use of this; I think it decreases clarity, and barely shaves off any characters from equivalent "pointful" expressions.
I think it quite compelling. An example:
asSeconds :: Hour h -> Minute m -> Second s -> Second t - -- | asSeconds take some 'TimeUnit's and convert them to 'Second's. asSeconds h m s = MkSecond $ 3600 * timeVal h + 60 * timeVal m + timeVal s
hmsToDiffTime :: Hour h -> Minute m -> Second s -> DiffTime - -- | 'hmsToDiffTime' converts time of day in hours, minutes and seconds to the - -- time from midnight as a 'DiffTime'. hmsToDiffTime = (secondsToDiffTime . timeVal) .:. asSeconds
As for putting it in base -- meh. I use the composition package, or define it myself. So I agree with Oleg; -1. - -- Alexander alexander@plaimi.net https://secure.plaimi.net/~alexander -----BEGIN PGP SIGNATURE----- Version: GnuPG v2
iQIcBAEBCgAGBQJXtwTXAAoJENQqWdRUGk8BP/UQAIcKzqVRhkVs0qtFDneTpSIi jLPPXMELbMnQe/ZQH2c5SaVM4+eDJIky33FEzrh9FWMeDftz1QFrsC+pPq+5/Esw U3h1HJrAJKl+zZ/bC1GQj9ObWKNROj3jEEt9pyNBcoHpxVnCohD3Y6Gx2LknE7m0 hnFlO0rCZZamk+pSeSlmLkkDM/MNxTx/FQcuZT0omxZtvzrz4cN7a069Gx35C+vr RK6NpiD5NUqTvMCL0zeI2yRpg2GV2PQcwV0CEWjLCsJYMcoeiF8+prSBdwzatgjH 7k1bHUdGwvcRzB74dyxIOPyHBgIDUFzj7bcE+NT0V20WXaz/Jgl73zZaIG9XtW19 aJ+RzW+aBSLEh8+uERc+Al9NpM9dLR94mDWIK/MZWEmlFHo8+W/md27+OxvM5BOr YCRpoQYeYDkepTAyRK2wRlszFXydDze8K6PMAq4DUE7xtUXofEbcodWA0quLxP4N ro2A8E4kqnO6BVD7iN+qch8TxmEiVYpqZnAjNz8eSyQCdn9UORpcMLT8yQ963nml 17yKRjHYDwg/g8EC1UjqJ9KwVFRhqQwdk//IupRyZ/5PPkEChy8t/ZjmmGKfLy0H CfhpRiNi0ozR+bYpUJcOdNM0ckCzgq5++9+M643RGjNWvD4fKDI8idNNn9eLlcom kaABFBC5Gbx2O6/rgpHc =X/Rb -----END PGP SIGNATURE----- _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

Well... there's that rather worrisome introductory paragraph of the
Data.Composition docs, though:
"This module is for convenience and demonstrative purposes more than it is
for providing actual value. I do not recommend that you rely on this module
for performance-sensitive code. Because this module is not based on
Prelude's (.), some chances at optimization might be missed by your
compiler."
On Fri, Aug 19, 2016 at 7:51 AM, Alex Belanger
I didn't even know about the composition package. I just wanted it to be readily available to everyone.
A quick look, `composition` seems really nice and is probably more aligned with Haskell ecosystem's philosophy of keeping base to what is only stricly needed by GHC.
These were some valuable feedback. I think I got my answer and we can let the thread die (:
Much appreciated, Alex
On Aug 19, 2016 9:08 AM, "Alexander Berntsen"
wrote: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512
On 18/08/16 23:57, Mike Ledger wrote:
IMO: I've never seen a compelling use of this; I think it decreases clarity, and barely shaves off any characters from equivalent "pointful" expressions.
I think it quite compelling. An example:
asSeconds :: Hour h -> Minute m -> Second s -> Second t - -- | asSeconds take some 'TimeUnit's and convert them to 'Second's. asSeconds h m s = MkSecond $ 3600 * timeVal h + 60 * timeVal m + timeVal s
hmsToDiffTime :: Hour h -> Minute m -> Second s -> DiffTime - -- | 'hmsToDiffTime' converts time of day in hours, minutes and seconds to the - -- time from midnight as a 'DiffTime'. hmsToDiffTime = (secondsToDiffTime . timeVal) .:. asSeconds
As for putting it in base -- meh. I use the composition package, or define it myself. So I agree with Oleg; -1. - -- Alexander alexander@plaimi.net https://secure.plaimi.net/~alexander -----BEGIN PGP SIGNATURE----- Version: GnuPG v2
iQIcBAEBCgAGBQJXtwTXAAoJENQqWdRUGk8BP/UQAIcKzqVRhkVs0qtFDneTpSIi jLPPXMELbMnQe/ZQH2c5SaVM4+eDJIky33FEzrh9FWMeDftz1QFrsC+pPq+5/Esw U3h1HJrAJKl+zZ/bC1GQj9ObWKNROj3jEEt9pyNBcoHpxVnCohD3Y6Gx2LknE7m0 hnFlO0rCZZamk+pSeSlmLkkDM/MNxTx/FQcuZT0omxZtvzrz4cN7a069Gx35C+vr RK6NpiD5NUqTvMCL0zeI2yRpg2GV2PQcwV0CEWjLCsJYMcoeiF8+prSBdwzatgjH 7k1bHUdGwvcRzB74dyxIOPyHBgIDUFzj7bcE+NT0V20WXaz/Jgl73zZaIG9XtW19 aJ+RzW+aBSLEh8+uERc+Al9NpM9dLR94mDWIK/MZWEmlFHo8+W/md27+OxvM5BOr YCRpoQYeYDkepTAyRK2wRlszFXydDze8K6PMAq4DUE7xtUXofEbcodWA0quLxP4N ro2A8E4kqnO6BVD7iN+qch8TxmEiVYpqZnAjNz8eSyQCdn9UORpcMLT8yQ963nml 17yKRjHYDwg/g8EC1UjqJ9KwVFRhqQwdk//IupRyZ/5PPkEChy8t/ZjmmGKfLy0H CfhpRiNi0ozR+bYpUJcOdNM0ckCzgq5++9+M643RGjNWvD4fKDI8idNNn9eLlcom kaABFBC5Gbx2O6/rgpHc =X/Rb -----END PGP SIGNATURE----- _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

Hi, Am Freitag, den 19.08.2016, 11:16 -0700 schrieb Theodore Lief Gannon:
Well... there's that rather worrisome introductory paragraph of the Data.Composition docs, though:
"This module is for convenience and demonstrative purposes more than it is for providing actual value. I do not recommend that you rely on this module for performance-sensitive code. Because this module is not based on Prelude's (.), some chances at optimization might be missed by your compiler."
I wonder if that is really something to worry about. Prelude’s (.) is not special in any way: -- | Function composition. {-# INLINE (.) #-} -- Make sure it has TWO args only on the left, so that it inlines -- when applied to two functions, even if there is no final argument (.) :: (b -> c) -> (a -> b) -> a -> c (.) f g = \x -> f (g x) The INLINE pragma and the definition with the right arity could be used in Data.Composition as well, and it would yield the same results. Greetings, Joachim -- Joachim “nomeata” Breitner mail@joachim-breitner.de • https://www.joachim-breitner.de/ XMPP: nomeata@joachim-breitner.de • OpenPGP-Key: 0xF0FBF51F Debian Developer: nomeata@debian.org

On Fri, Aug 19, 2016 at 2:50 PM, Joachim Breitner
Hi,
Am Freitag, den 19.08.2016, 11:16 -0700 schrieb Theodore Lief Gannon:
Well... there's that rather worrisome introductory paragraph of the Data.Composition docs, though:
"This module is for convenience and demonstrative purposes more than it is for providing actual value. I do not recommend that you rely on this module for performance-sensitive code. Because this module is not based on Prelude's (.), some chances at optimization might be missed by your compiler."
I wonder if that is really something to worry about. Prelude’s (.) is not special in any way:
<snip>
The INLINE pragma and the definition with the right arity could be used in Data.Composition as well, and it would yield the same results.
Any RULEs involving Prelude’s (.) would need to be copied as well.
--
Dave Menendez

On Fri, Aug 19, 2016 at 10:38 PM, David Menendez
Any RULEs involving Prelude’s (.) would need to be copied as well.
There aren't any, and if there are any then they're almost certainly broken. The INLINE pragma on (.) isn't marked with a simplifier phase, so it will be inlined almost immediately when optimization begins, as long as it has at least two arguments. There is no time for rules involving it to take effect. Rewrite rules end up working with the inlined version. For example, Data.Sequence has a rule saying forall f g xs . fmapSeq f (fmapSeq g xs) = fmapSeq (f . g) xs So if you write fmap f . fmap g for sequences, this will specialize to fmapSeq f . fmapSeq g and inline to \xs -> fmapSeq f (fmapSeq g xs) at which point the rewrite rule will fire, changing it to \xs -> fmapSeq (f . g) xs This, in turn, will inline as well, to \xs -> fmapSeq (\x -> f (g x)) xs

On Fri, Aug 19, 2016 at 11:50 AM, Joachim Breitner
Hi,
Am Freitag, den 19.08.2016, 11:16 -0700 schrieb Theodore Lief Gannon:
Well... there's that rather worrisome introductory paragraph of the Data.Composition docs, though:
"This module is for convenience and demonstrative purposes more than it is for providing actual value. I do not recommend that you rely on this module for performance-sensitive code. Because this module is not based on Prelude's (.), some chances at optimization might be missed by your compiler."
I wonder if that is really something to worry about. Prelude’s (.) is not special in any way:
Yes and no. Prelude's (.) is not special in that GHC doesn't identify it as something that must be treated differently from what's expected from the definition (as opposed to, say, ($)). However, (.) is inherently a special case because of performance issues about closures. For example, whether we define: (.) f g = \x -> f (g x) vs: (.) f g x = f (g x) has ramifications, though it's fairly easy to guess which one of those two will be most performant. However, it's much less clear which of the following definitions will be the most performant: (.:) = (.) . (.) (.:) f g = (f .) . g (.:) f g = \x y -> f (g x y) For the version implemented in pointless-fun:Data.Function.Pointless, I actually did some benchmarking to determine which was fastest. It is (a) faster by a surprisingly large margin, and (b) not the one I expected to be the fastest. I haven't run those benchmarks on the latest versions of GHC, but that just underscores the point. Because the performance difference is significant and unexpected, having a single blessed (and maintained!) definition would be beneficial to anyone who actually uses this function in production code— whether that blessed definition is in base or some other library everyone has and knows about. -- Live well, ~wren

On Mon, Aug 22, 2016 at 10:23:07PM -0700, wren romano wrote:
(.) f g = \x -> f (g x)
vs:
(.) f g x = f (g x)
has ramifications, though it's fairly easy to guess which one of those two will be most performant.
Are these not synonyms? What is the meaning of fargs var = expr if not fargs = \var -> expr ?

At the semantic level of "does my program compute correct results" they're identical. At the operational level of "how fast does my program run" they're different.
On August 23, 2016 5:09:19 PM GMT+10:00, Tom Ellis
On Mon, Aug 22, 2016 at 10:23:07PM -0700, wren romano wrote:
(.) f g = \x -> f (g x)
vs:
(.) f g x = f (g x)
has ramifications, though it's fairly easy to guess which one of
those
two will be most performant.
Are these not synonyms? What is the meaning of
fargs var = expr
if not
fargs = \var -> expr
? _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
-- Sent from my Android device with K-9 Mail. Please excuse my brevity.

On the contrary, they're exactly the same (on GHC 7.6.3): module Foo where comp1 f g x = f (g x) comp2 f g = \x -> f (g x) % ghc -O0 -dsuppress-all -fforce-recomp -no-link -ddump-prep test.hs [1 of 1] Compiling Foo ( test.hs, test.o ) ==================== CorePrep ==================== Result size of CorePrep = {terms: 24, types: 36, coercions: 0} comp2 comp2 = \ @ t_aeU @ t1_aeV @ t2_aeW f_sfz g_sfy x_sfx -> let { sat_sfI sat_sfI = g_sfy x_sfx } in f_sfz sat_sfI comp1 comp1 = \ @ t_af5 @ t1_af6 @ t2_af7 f_sfG g_sfF x_sfE -> let { sat_sfJ sat_sfJ = g_sfF x_sfE } in f_sfG sat_sfJ (the same holds for -O2, if you compile them separately) On Tue, Aug 23, 2016 at 05:19:38PM +1000, Ben wrote:
At the semantic level of "does my program compute correct results" they're identical. At the operational level of "how fast does my program run" they're different.
On August 23, 2016 5:09:19 PM GMT+10:00, Tom Ellis
wrote: On Mon, Aug 22, 2016 at 10:23:07PM -0700, wren romano wrote:
(.) f g = \x -> f (g x)
vs:
(.) f g x = f (g x)
has ramifications, though it's fairly easy to guess which one of
those
two will be most performant.
Are these not synonyms? What is the meaning of
fargs var = expr
if not
fargs = \var -> expr
?

I think the point which no-one has articulated yet is that the source-level arity of (.) affects whether GHC will decide to inline it. Only fully saturated applications are inlined, thus by having two explicit arguments GHC will inline (.) in the common case where is it used with two arguments which will improve optimisation opportunities for code which composes many functions. On the other hand, it is not very common to write
(.) f g x
which is why (.) is defined in such a way.
Matt
On Tue, Aug 23, 2016 at 8:33 AM, Tom Ellis
On the contrary, they're exactly the same (on GHC 7.6.3):
module Foo where
comp1 f g x = f (g x)
comp2 f g = \x -> f (g x)
% ghc -O0 -dsuppress-all -fforce-recomp -no-link -ddump-prep test.hs [1 of 1] Compiling Foo ( test.hs, test.o )
==================== CorePrep ==================== Result size of CorePrep = {terms: 24, types: 36, coercions: 0}
comp2 comp2 = \ @ t_aeU @ t1_aeV @ t2_aeW f_sfz g_sfy x_sfx -> let { sat_sfI sat_sfI = g_sfy x_sfx } in f_sfz sat_sfI
comp1 comp1 = \ @ t_af5 @ t1_af6 @ t2_af7 f_sfG g_sfF x_sfE -> let { sat_sfJ sat_sfJ = g_sfF x_sfE } in f_sfG sat_sfJ
(the same holds for -O2, if you compile them separately)
On Tue, Aug 23, 2016 at 05:19:38PM +1000, Ben wrote:
At the semantic level of "does my program compute correct results" they're identical. At the operational level of "how fast does my program run" they're different.
On August 23, 2016 5:09:19 PM GMT+10:00, Tom Ellis
wrote: On Mon, Aug 22, 2016 at 10:23:07PM -0700, wren romano wrote:
(.) f g = \x -> f (g x)
vs:
(.) f g x = f (g x)
has ramifications, though it's fairly easy to guess which one of
those
two will be most performant.
Are these not synonyms? What is the meaning of
fargs var = expr
if not
fargs = \var -> expr
?
Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

*Very* interesting. Here is the key section of the GHC users guide: GHC will only inline the function if it is fully applied, where “fully applied” means applied to as many arguments as appear (syntactically) on the LHS of the function definition That this is a good heuristic is *extremely* counterintuitive to me. I would have supposed that being more explicit, for example {-# INLINE (.) f g #-} to inline on all static applications of at least two arguments would have been a much clearer way to communicate this message. What's the rationale behind the current behaviour? Tom On Tue, Aug 23, 2016 at 09:56:25AM +0100, Matthew Pickering wrote:
I think the point which no-one has articulated yet is that the source-level arity of (.) affects whether GHC will decide to inline it.
Only fully saturated applications are inlined [...]
On Tue, Aug 23, 2016 at 8:33 AM, Tom Ellis
wrote: On the contrary, they're exactly the same (on GHC 7.6.3):
module Foo where
comp1 f g x = f (g x)
comp2 f g = \x -> f (g x)
% ghc -O0 -dsuppress-all -fforce-recomp -no-link -ddump-prep test.hs [1 of 1] Compiling Foo ( test.hs, test.o )
==================== CorePrep ==================== Result size of CorePrep = {terms: 24, types: 36, coercions: 0}
comp2 comp2 = \ @ t_aeU @ t1_aeV @ t2_aeW f_sfz g_sfy x_sfx -> let { sat_sfI sat_sfI = g_sfy x_sfx } in f_sfz sat_sfI
comp1 comp1 = \ @ t_af5 @ t1_af6 @ t2_af7 f_sfG g_sfF x_sfE -> let { sat_sfJ sat_sfJ = g_sfF x_sfE } in f_sfG sat_sfJ
(the same holds for -O2, if you compile them separately)
On Tue, Aug 23, 2016 at 05:19:38PM +1000, Ben wrote:
At the semantic level of "does my program compute correct results" they're identical. At the operational level of "how fast does my program run" they're different.
On August 23, 2016 5:09:19 PM GMT+10:00, Tom Ellis
wrote: On Mon, Aug 22, 2016 at 10:23:07PM -0700, wren romano wrote:
(.) f g = \x -> f (g x)
vs:
(.) f g x = f (g x)
has ramifications, though it's fairly easy to guess which one of
those
two will be most performant.
Are these not synonyms? What is the meaning of
fargs var = expr
if not
fargs = \var -> expr
?

Suddenly the eta reduce hlint warning becomes much more important. Alan On 23 Aug 2016 11:22 a.m., "Tom Ellis" < tom-lists-haskell-cafe-2013@jaguarpaw.co.uk> wrote:
*Very* interesting. Here is the key section of the GHC users guide:
GHC will only inline the function if it is fully applied, where “fully applied” means applied to as many arguments as appear (syntactically) on the LHS of the function definition
That this is a good heuristic is *extremely* counterintuitive to me. I would have supposed that being more explicit, for example
{-# INLINE (.) f g #-}
to inline on all static applications of at least two arguments would have been a much clearer way to communicate this message.
What's the rationale behind the current behaviour?
Tom
I think the point which no-one has articulated yet is that the source-level arity of (.) affects whether GHC will decide to inline it.
Only fully saturated applications are inlined [...]
On Tue, Aug 23, 2016 at 8:33 AM, Tom Ellis
wrote: On the contrary, they're exactly the same (on GHC 7.6.3):
module Foo where
comp1 f g x = f (g x)
comp2 f g = \x -> f (g x)
% ghc -O0 -dsuppress-all -fforce-recomp -no-link -ddump-prep test.hs [1 of 1] Compiling Foo ( test.hs, test.o )
==================== CorePrep ==================== Result size of CorePrep = {terms: 24, types: 36, coercions: 0}
comp2 comp2 = \ @ t_aeU @ t1_aeV @ t2_aeW f_sfz g_sfy x_sfx -> let { sat_sfI sat_sfI = g_sfy x_sfx } in f_sfz sat_sfI
comp1 comp1 = \ @ t_af5 @ t1_af6 @ t2_af7 f_sfG g_sfF x_sfE -> let { sat_sfJ sat_sfJ = g_sfF x_sfE } in f_sfG sat_sfJ
(the same holds for -O2, if you compile them separately)
On Tue, Aug 23, 2016 at 05:19:38PM +1000, Ben wrote:
At the semantic level of "does my program compute correct results"
On Tue, Aug 23, 2016 at 09:56:25AM +0100, Matthew Pickering wrote: they're
identical. At the operational level of "how fast does my program run" they're different.
On August 23, 2016 5:09:19 PM GMT+10:00, Tom Ellis < tom-lists-haskell-cafe-2013@jaguarpaw.co.uk> wrote:
On Mon, Aug 22, 2016 at 10:23:07PM -0700, wren romano wrote:
(.) f g = \x -> f (g x)
vs:
(.) f g x = f (g x)
has ramifications, though it's fairly easy to guess which one of
those
two will be most performant.
Are these not synonyms? What is the meaning of
fargs var = expr
if not
fargs = \var -> expr
?
Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
participants (12)
-
Alan & Kim Zimmerman
-
Alex Belanger
-
Alexander Berntsen
-
Ben
-
David Feuer
-
David Menendez
-
Joachim Breitner
-
Matthew Pickering
-
Mike Ledger
-
Theodore Lief Gannon
-
Tom Ellis
-
wren romano