How to write this function in point-free style?












-12















How to rewrite the following function in point-free style, removing the parameter x from the definition completely (the other two may stay):



between min max x = (min < x) && (x < max)


This is not an assignment, just a question. I don't know how to proceed. I can turn it into a lambda function



between min max = x -> (min < x) && (x < max)


but this is not point-free, as x is still there. Please help.










share|improve this question




















  • 5





    is this an assignment? what have you tried? BTW calling your values by names of built-in functions is confusing. Better use minval and maxval.

    – Will Ness
    Nov 20 '18 at 11:19








  • 2





    You might want to look at the documentation for liftA2 in module Control.Applicative

    – mschmidt
    Nov 20 '18 at 11:56






  • 3





    There's no compelling reason to write this particular function in point-free style. This version is quite readable as-is.

    – chepner
    Nov 20 '18 at 14:05






  • 4





    This question is being discussed in Meta

    – yivi
    Nov 21 '18 at 11:54






  • 3





    OK, so after the edit, and while the new 3rd vote for deletion is not cast, what have you tried? Where exactly is your difficulty? Have you yourself tried to find a solution? What code snippets have you written? Do you know about "operator sections"? Do you know about "combinators"? (these are googlable terms). Do you know e.g. about transforming sin (cos x) to (sin . cos) x? Do you know about "eta reduction"?

    – Will Ness
    Nov 21 '18 at 15:17


















-12















How to rewrite the following function in point-free style, removing the parameter x from the definition completely (the other two may stay):



between min max x = (min < x) && (x < max)


This is not an assignment, just a question. I don't know how to proceed. I can turn it into a lambda function



between min max = x -> (min < x) && (x < max)


but this is not point-free, as x is still there. Please help.










share|improve this question




















  • 5





    is this an assignment? what have you tried? BTW calling your values by names of built-in functions is confusing. Better use minval and maxval.

    – Will Ness
    Nov 20 '18 at 11:19








  • 2





    You might want to look at the documentation for liftA2 in module Control.Applicative

    – mschmidt
    Nov 20 '18 at 11:56






  • 3





    There's no compelling reason to write this particular function in point-free style. This version is quite readable as-is.

    – chepner
    Nov 20 '18 at 14:05






  • 4





    This question is being discussed in Meta

    – yivi
    Nov 21 '18 at 11:54






  • 3





    OK, so after the edit, and while the new 3rd vote for deletion is not cast, what have you tried? Where exactly is your difficulty? Have you yourself tried to find a solution? What code snippets have you written? Do you know about "operator sections"? Do you know about "combinators"? (these are googlable terms). Do you know e.g. about transforming sin (cos x) to (sin . cos) x? Do you know about "eta reduction"?

    – Will Ness
    Nov 21 '18 at 15:17
















-12












-12








-12








How to rewrite the following function in point-free style, removing the parameter x from the definition completely (the other two may stay):



between min max x = (min < x) && (x < max)


This is not an assignment, just a question. I don't know how to proceed. I can turn it into a lambda function



between min max = x -> (min < x) && (x < max)


but this is not point-free, as x is still there. Please help.










share|improve this question
















How to rewrite the following function in point-free style, removing the parameter x from the definition completely (the other two may stay):



between min max x = (min < x) && (x < max)


This is not an assignment, just a question. I don't know how to proceed. I can turn it into a lambda function



between min max = x -> (min < x) && (x < max)


but this is not point-free, as x is still there. Please help.







haskell functional-programming pointfree tacit-programming






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 21 '18 at 16:22









Will Ness

45.5k468124




45.5k468124










asked Nov 20 '18 at 11:09









user2304996user2304996

14618




14618








  • 5





    is this an assignment? what have you tried? BTW calling your values by names of built-in functions is confusing. Better use minval and maxval.

    – Will Ness
    Nov 20 '18 at 11:19








  • 2





    You might want to look at the documentation for liftA2 in module Control.Applicative

    – mschmidt
    Nov 20 '18 at 11:56






  • 3





    There's no compelling reason to write this particular function in point-free style. This version is quite readable as-is.

    – chepner
    Nov 20 '18 at 14:05






  • 4





    This question is being discussed in Meta

    – yivi
    Nov 21 '18 at 11:54






  • 3





    OK, so after the edit, and while the new 3rd vote for deletion is not cast, what have you tried? Where exactly is your difficulty? Have you yourself tried to find a solution? What code snippets have you written? Do you know about "operator sections"? Do you know about "combinators"? (these are googlable terms). Do you know e.g. about transforming sin (cos x) to (sin . cos) x? Do you know about "eta reduction"?

    – Will Ness
    Nov 21 '18 at 15:17
















  • 5





    is this an assignment? what have you tried? BTW calling your values by names of built-in functions is confusing. Better use minval and maxval.

    – Will Ness
    Nov 20 '18 at 11:19








  • 2





    You might want to look at the documentation for liftA2 in module Control.Applicative

    – mschmidt
    Nov 20 '18 at 11:56






  • 3





    There's no compelling reason to write this particular function in point-free style. This version is quite readable as-is.

    – chepner
    Nov 20 '18 at 14:05






  • 4





    This question is being discussed in Meta

    – yivi
    Nov 21 '18 at 11:54






  • 3





    OK, so after the edit, and while the new 3rd vote for deletion is not cast, what have you tried? Where exactly is your difficulty? Have you yourself tried to find a solution? What code snippets have you written? Do you know about "operator sections"? Do you know about "combinators"? (these are googlable terms). Do you know e.g. about transforming sin (cos x) to (sin . cos) x? Do you know about "eta reduction"?

    – Will Ness
    Nov 21 '18 at 15:17










5




5





is this an assignment? what have you tried? BTW calling your values by names of built-in functions is confusing. Better use minval and maxval.

– Will Ness
Nov 20 '18 at 11:19







is this an assignment? what have you tried? BTW calling your values by names of built-in functions is confusing. Better use minval and maxval.

– Will Ness
Nov 20 '18 at 11:19






2




2





You might want to look at the documentation for liftA2 in module Control.Applicative

– mschmidt
Nov 20 '18 at 11:56





You might want to look at the documentation for liftA2 in module Control.Applicative

– mschmidt
Nov 20 '18 at 11:56




3




3





There's no compelling reason to write this particular function in point-free style. This version is quite readable as-is.

– chepner
Nov 20 '18 at 14:05





There's no compelling reason to write this particular function in point-free style. This version is quite readable as-is.

– chepner
Nov 20 '18 at 14:05




4




4





This question is being discussed in Meta

– yivi
Nov 21 '18 at 11:54





This question is being discussed in Meta

– yivi
Nov 21 '18 at 11:54




3




3





OK, so after the edit, and while the new 3rd vote for deletion is not cast, what have you tried? Where exactly is your difficulty? Have you yourself tried to find a solution? What code snippets have you written? Do you know about "operator sections"? Do you know about "combinators"? (these are googlable terms). Do you know e.g. about transforming sin (cos x) to (sin . cos) x? Do you know about "eta reduction"?

– Will Ness
Nov 21 '18 at 15:17







OK, so after the edit, and while the new 3rd vote for deletion is not cast, what have you tried? Where exactly is your difficulty? Have you yourself tried to find a solution? What code snippets have you written? Do you know about "operator sections"? Do you know about "combinators"? (these are googlable terms). Do you know e.g. about transforming sin (cos x) to (sin . cos) x? Do you know about "eta reduction"?

– Will Ness
Nov 21 '18 at 15:17














4 Answers
4






active

oldest

votes


















5














Another solution (needs import of Control.Applicative):



between min max = liftA2 (&&) (min <) (max >)





share|improve this answer





















  • 1





    and with (<&&>) = liftA2 (&&) it becomes the almost readable (min <) <&&> (max >). BTW there are these definitions somewhere, (<^) = flip fmap and (^>) = (<*>), such that it becomes the nearly identical-looking (min <) <^(&&)^> (max >).

    – Will Ness
    Nov 21 '18 at 11:18



















8














It can be done using the Reader applicative:



between min max = x. (min < x) && (x < max)
{ Convert infix comparisons to sections }
= x. ((min <) x) && ((< max) x)
{ Move infix (&&) to applicative style }
= x. (&&) ((min <) x) ((< max) x)
{ Lift to applicative style using the applicative instance of `(->) a` }
= x. (pure (&&) <*> (min <) <*> (< max)) x
{ Eta-reduce }
= pure (&&) <*> (min <) <*> (< max)
{ Optionally simplify for idiomatic style }
= (&&) <$> (min <) <*> (< max)





share|improve this answer































    4














    Using Control.Arrow we can reach this nearly obfuscated code:



    (min <) &&& (< max) >>> uncurry (&&)


    This relies on the predefined >>> for left-to-right composition, f &&& g = x -> (f x, g x), and uncurrying.





    pointfree.io also suggests the following unreadable code:



    between = (. flip (<)) . ap . ((&&) .) . (<)





    share|improve this answer


























    • It almost seems like you're trying to discourage point-free style here :)

      – chepner
      Nov 20 '18 at 14:04











    • well, flip (<) is the same as (>), so you can save a few characters there ;)

      – M. Aroosi
      Nov 20 '18 at 17:56











    • Alternatively and even shorter: liftA2 (&&) (min <) (max >)

      – mschmidt
      Nov 20 '18 at 18:30











    • @chepner I'm trying my best :) Actually, I'm in favor of point-free but against point-less. The main issue is that the difference between those can be quite subtle.

      – chi
      Nov 20 '18 at 19:14






    • 1





      also, and . sequence [(min <), (max >)].

      – Will Ness
      Nov 21 '18 at 15:23



















    2














    By operator sections transformation,



    between min max x = (min < x) && (x < max)
    = ((&&) . (min <)) x ((< max) x)


    Now this fits a pattern for S-combinator, S f g x = (f x) (g x). There are many ways of encoding it in Haskell, but the main two are via Applicative and via Arrows:



        _S f g x = (f x) (g x)
    = (f <*> g) x
    = uncurry id . (f &&& g) $ x


    The second gives us



    between a z = uncurry (&&) . ((a <) &&& (< z))


    And the first, even more fitting



    between a z = (&&) <$> (a <) <*> (< z)
    = liftA2 (&&) (a <) (< z)
    = (a <) <^(&&)^> (< z) -- nice and visual

    (<^) = flip (<$>)
    (^>) = (<*>)


    But we could also fiddle with other combinators, with much less satisfactory results though,



        _S f g x = f x (g x)
    = flip f (g x) x
    = (flip f . g) x x
    = join (flip f <$> g) x
    = (flip f =<< g) x


    or



                 = (f x . g) x
    = (. g) (f x) x
    = ((. g) =<< f) x


    which illustrates nicely the dangers of pointlessness in the pursuit of the pointfree.



    There's one more possibility that makes sense (syntactically), which is



        _S f g x = (f x) (g x)
    -- = foldr1 ($) . sequence [f,g] $ x -- not valid Haskell

    -- sequence [f,g] x = [f x,g x]


    This is not a valid Haskell in general because of the typing issues, but in our specific case it does give rise to one more valid definition, which also does seem to follow the inner logic of it nicely,



    between a z = -- foldr1 ($) . sequence [(&&).(a <), (< z)] -- not OK
    = foldr1 (&&) . sequence [(a <), (< z)] -- OK
    = and . sequence [(a <), (> z)]


    because (a <) and (> z) have the same type.






    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53391699%2fhow-to-write-this-function-in-point-free-style%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      5














      Another solution (needs import of Control.Applicative):



      between min max = liftA2 (&&) (min <) (max >)





      share|improve this answer





















      • 1





        and with (<&&>) = liftA2 (&&) it becomes the almost readable (min <) <&&> (max >). BTW there are these definitions somewhere, (<^) = flip fmap and (^>) = (<*>), such that it becomes the nearly identical-looking (min <) <^(&&)^> (max >).

        – Will Ness
        Nov 21 '18 at 11:18
















      5














      Another solution (needs import of Control.Applicative):



      between min max = liftA2 (&&) (min <) (max >)





      share|improve this answer





















      • 1





        and with (<&&>) = liftA2 (&&) it becomes the almost readable (min <) <&&> (max >). BTW there are these definitions somewhere, (<^) = flip fmap and (^>) = (<*>), such that it becomes the nearly identical-looking (min <) <^(&&)^> (max >).

        – Will Ness
        Nov 21 '18 at 11:18














      5












      5








      5







      Another solution (needs import of Control.Applicative):



      between min max = liftA2 (&&) (min <) (max >)





      share|improve this answer















      Another solution (needs import of Control.Applicative):



      between min max = liftA2 (&&) (min <) (max >)






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 20 '18 at 20:58

























      answered Nov 20 '18 at 18:34









      mschmidtmschmidt

      1,96941019




      1,96941019








      • 1





        and with (<&&>) = liftA2 (&&) it becomes the almost readable (min <) <&&> (max >). BTW there are these definitions somewhere, (<^) = flip fmap and (^>) = (<*>), such that it becomes the nearly identical-looking (min <) <^(&&)^> (max >).

        – Will Ness
        Nov 21 '18 at 11:18














      • 1





        and with (<&&>) = liftA2 (&&) it becomes the almost readable (min <) <&&> (max >). BTW there are these definitions somewhere, (<^) = flip fmap and (^>) = (<*>), such that it becomes the nearly identical-looking (min <) <^(&&)^> (max >).

        – Will Ness
        Nov 21 '18 at 11:18








      1




      1





      and with (<&&>) = liftA2 (&&) it becomes the almost readable (min <) <&&> (max >). BTW there are these definitions somewhere, (<^) = flip fmap and (^>) = (<*>), such that it becomes the nearly identical-looking (min <) <^(&&)^> (max >).

      – Will Ness
      Nov 21 '18 at 11:18





      and with (<&&>) = liftA2 (&&) it becomes the almost readable (min <) <&&> (max >). BTW there are these definitions somewhere, (<^) = flip fmap and (^>) = (<*>), such that it becomes the nearly identical-looking (min <) <^(&&)^> (max >).

      – Will Ness
      Nov 21 '18 at 11:18













      8














      It can be done using the Reader applicative:



      between min max = x. (min < x) && (x < max)
      { Convert infix comparisons to sections }
      = x. ((min <) x) && ((< max) x)
      { Move infix (&&) to applicative style }
      = x. (&&) ((min <) x) ((< max) x)
      { Lift to applicative style using the applicative instance of `(->) a` }
      = x. (pure (&&) <*> (min <) <*> (< max)) x
      { Eta-reduce }
      = pure (&&) <*> (min <) <*> (< max)
      { Optionally simplify for idiomatic style }
      = (&&) <$> (min <) <*> (< max)





      share|improve this answer




























        8














        It can be done using the Reader applicative:



        between min max = x. (min < x) && (x < max)
        { Convert infix comparisons to sections }
        = x. ((min <) x) && ((< max) x)
        { Move infix (&&) to applicative style }
        = x. (&&) ((min <) x) ((< max) x)
        { Lift to applicative style using the applicative instance of `(->) a` }
        = x. (pure (&&) <*> (min <) <*> (< max)) x
        { Eta-reduce }
        = pure (&&) <*> (min <) <*> (< max)
        { Optionally simplify for idiomatic style }
        = (&&) <$> (min <) <*> (< max)





        share|improve this answer


























          8












          8








          8







          It can be done using the Reader applicative:



          between min max = x. (min < x) && (x < max)
          { Convert infix comparisons to sections }
          = x. ((min <) x) && ((< max) x)
          { Move infix (&&) to applicative style }
          = x. (&&) ((min <) x) ((< max) x)
          { Lift to applicative style using the applicative instance of `(->) a` }
          = x. (pure (&&) <*> (min <) <*> (< max)) x
          { Eta-reduce }
          = pure (&&) <*> (min <) <*> (< max)
          { Optionally simplify for idiomatic style }
          = (&&) <$> (min <) <*> (< max)





          share|improve this answer













          It can be done using the Reader applicative:



          between min max = x. (min < x) && (x < max)
          { Convert infix comparisons to sections }
          = x. ((min <) x) && ((< max) x)
          { Move infix (&&) to applicative style }
          = x. (&&) ((min <) x) ((< max) x)
          { Lift to applicative style using the applicative instance of `(->) a` }
          = x. (pure (&&) <*> (min <) <*> (< max)) x
          { Eta-reduce }
          = pure (&&) <*> (min <) <*> (< max)
          { Optionally simplify for idiomatic style }
          = (&&) <$> (min <) <*> (< max)






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 20 '18 at 11:27









          KrisKris

          635313




          635313























              4














              Using Control.Arrow we can reach this nearly obfuscated code:



              (min <) &&& (< max) >>> uncurry (&&)


              This relies on the predefined >>> for left-to-right composition, f &&& g = x -> (f x, g x), and uncurrying.





              pointfree.io also suggests the following unreadable code:



              between = (. flip (<)) . ap . ((&&) .) . (<)





              share|improve this answer


























              • It almost seems like you're trying to discourage point-free style here :)

                – chepner
                Nov 20 '18 at 14:04











              • well, flip (<) is the same as (>), so you can save a few characters there ;)

                – M. Aroosi
                Nov 20 '18 at 17:56











              • Alternatively and even shorter: liftA2 (&&) (min <) (max >)

                – mschmidt
                Nov 20 '18 at 18:30











              • @chepner I'm trying my best :) Actually, I'm in favor of point-free but against point-less. The main issue is that the difference between those can be quite subtle.

                – chi
                Nov 20 '18 at 19:14






              • 1





                also, and . sequence [(min <), (max >)].

                – Will Ness
                Nov 21 '18 at 15:23
















              4














              Using Control.Arrow we can reach this nearly obfuscated code:



              (min <) &&& (< max) >>> uncurry (&&)


              This relies on the predefined >>> for left-to-right composition, f &&& g = x -> (f x, g x), and uncurrying.





              pointfree.io also suggests the following unreadable code:



              between = (. flip (<)) . ap . ((&&) .) . (<)





              share|improve this answer


























              • It almost seems like you're trying to discourage point-free style here :)

                – chepner
                Nov 20 '18 at 14:04











              • well, flip (<) is the same as (>), so you can save a few characters there ;)

                – M. Aroosi
                Nov 20 '18 at 17:56











              • Alternatively and even shorter: liftA2 (&&) (min <) (max >)

                – mschmidt
                Nov 20 '18 at 18:30











              • @chepner I'm trying my best :) Actually, I'm in favor of point-free but against point-less. The main issue is that the difference between those can be quite subtle.

                – chi
                Nov 20 '18 at 19:14






              • 1





                also, and . sequence [(min <), (max >)].

                – Will Ness
                Nov 21 '18 at 15:23














              4












              4








              4







              Using Control.Arrow we can reach this nearly obfuscated code:



              (min <) &&& (< max) >>> uncurry (&&)


              This relies on the predefined >>> for left-to-right composition, f &&& g = x -> (f x, g x), and uncurrying.





              pointfree.io also suggests the following unreadable code:



              between = (. flip (<)) . ap . ((&&) .) . (<)





              share|improve this answer















              Using Control.Arrow we can reach this nearly obfuscated code:



              (min <) &&& (< max) >>> uncurry (&&)


              This relies on the predefined >>> for left-to-right composition, f &&& g = x -> (f x, g x), and uncurrying.





              pointfree.io also suggests the following unreadable code:



              between = (. flip (<)) . ap . ((&&) .) . (<)






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Nov 20 '18 at 13:56

























              answered Nov 20 '18 at 13:42









              chichi

              74.6k284140




              74.6k284140













              • It almost seems like you're trying to discourage point-free style here :)

                – chepner
                Nov 20 '18 at 14:04











              • well, flip (<) is the same as (>), so you can save a few characters there ;)

                – M. Aroosi
                Nov 20 '18 at 17:56











              • Alternatively and even shorter: liftA2 (&&) (min <) (max >)

                – mschmidt
                Nov 20 '18 at 18:30











              • @chepner I'm trying my best :) Actually, I'm in favor of point-free but against point-less. The main issue is that the difference between those can be quite subtle.

                – chi
                Nov 20 '18 at 19:14






              • 1





                also, and . sequence [(min <), (max >)].

                – Will Ness
                Nov 21 '18 at 15:23



















              • It almost seems like you're trying to discourage point-free style here :)

                – chepner
                Nov 20 '18 at 14:04











              • well, flip (<) is the same as (>), so you can save a few characters there ;)

                – M. Aroosi
                Nov 20 '18 at 17:56











              • Alternatively and even shorter: liftA2 (&&) (min <) (max >)

                – mschmidt
                Nov 20 '18 at 18:30











              • @chepner I'm trying my best :) Actually, I'm in favor of point-free but against point-less. The main issue is that the difference between those can be quite subtle.

                – chi
                Nov 20 '18 at 19:14






              • 1





                also, and . sequence [(min <), (max >)].

                – Will Ness
                Nov 21 '18 at 15:23

















              It almost seems like you're trying to discourage point-free style here :)

              – chepner
              Nov 20 '18 at 14:04





              It almost seems like you're trying to discourage point-free style here :)

              – chepner
              Nov 20 '18 at 14:04













              well, flip (<) is the same as (>), so you can save a few characters there ;)

              – M. Aroosi
              Nov 20 '18 at 17:56





              well, flip (<) is the same as (>), so you can save a few characters there ;)

              – M. Aroosi
              Nov 20 '18 at 17:56













              Alternatively and even shorter: liftA2 (&&) (min <) (max >)

              – mschmidt
              Nov 20 '18 at 18:30





              Alternatively and even shorter: liftA2 (&&) (min <) (max >)

              – mschmidt
              Nov 20 '18 at 18:30













              @chepner I'm trying my best :) Actually, I'm in favor of point-free but against point-less. The main issue is that the difference between those can be quite subtle.

              – chi
              Nov 20 '18 at 19:14





              @chepner I'm trying my best :) Actually, I'm in favor of point-free but against point-less. The main issue is that the difference between those can be quite subtle.

              – chi
              Nov 20 '18 at 19:14




              1




              1





              also, and . sequence [(min <), (max >)].

              – Will Ness
              Nov 21 '18 at 15:23





              also, and . sequence [(min <), (max >)].

              – Will Ness
              Nov 21 '18 at 15:23











              2














              By operator sections transformation,



              between min max x = (min < x) && (x < max)
              = ((&&) . (min <)) x ((< max) x)


              Now this fits a pattern for S-combinator, S f g x = (f x) (g x). There are many ways of encoding it in Haskell, but the main two are via Applicative and via Arrows:



                  _S f g x = (f x) (g x)
              = (f <*> g) x
              = uncurry id . (f &&& g) $ x


              The second gives us



              between a z = uncurry (&&) . ((a <) &&& (< z))


              And the first, even more fitting



              between a z = (&&) <$> (a <) <*> (< z)
              = liftA2 (&&) (a <) (< z)
              = (a <) <^(&&)^> (< z) -- nice and visual

              (<^) = flip (<$>)
              (^>) = (<*>)


              But we could also fiddle with other combinators, with much less satisfactory results though,



                  _S f g x = f x (g x)
              = flip f (g x) x
              = (flip f . g) x x
              = join (flip f <$> g) x
              = (flip f =<< g) x


              or



                           = (f x . g) x
              = (. g) (f x) x
              = ((. g) =<< f) x


              which illustrates nicely the dangers of pointlessness in the pursuit of the pointfree.



              There's one more possibility that makes sense (syntactically), which is



                  _S f g x = (f x) (g x)
              -- = foldr1 ($) . sequence [f,g] $ x -- not valid Haskell

              -- sequence [f,g] x = [f x,g x]


              This is not a valid Haskell in general because of the typing issues, but in our specific case it does give rise to one more valid definition, which also does seem to follow the inner logic of it nicely,



              between a z = -- foldr1 ($) . sequence [(&&).(a <), (< z)] -- not OK
              = foldr1 (&&) . sequence [(a <), (< z)] -- OK
              = and . sequence [(a <), (> z)]


              because (a <) and (> z) have the same type.






              share|improve this answer




























                2














                By operator sections transformation,



                between min max x = (min < x) && (x < max)
                = ((&&) . (min <)) x ((< max) x)


                Now this fits a pattern for S-combinator, S f g x = (f x) (g x). There are many ways of encoding it in Haskell, but the main two are via Applicative and via Arrows:



                    _S f g x = (f x) (g x)
                = (f <*> g) x
                = uncurry id . (f &&& g) $ x


                The second gives us



                between a z = uncurry (&&) . ((a <) &&& (< z))


                And the first, even more fitting



                between a z = (&&) <$> (a <) <*> (< z)
                = liftA2 (&&) (a <) (< z)
                = (a <) <^(&&)^> (< z) -- nice and visual

                (<^) = flip (<$>)
                (^>) = (<*>)


                But we could also fiddle with other combinators, with much less satisfactory results though,



                    _S f g x = f x (g x)
                = flip f (g x) x
                = (flip f . g) x x
                = join (flip f <$> g) x
                = (flip f =<< g) x


                or



                             = (f x . g) x
                = (. g) (f x) x
                = ((. g) =<< f) x


                which illustrates nicely the dangers of pointlessness in the pursuit of the pointfree.



                There's one more possibility that makes sense (syntactically), which is



                    _S f g x = (f x) (g x)
                -- = foldr1 ($) . sequence [f,g] $ x -- not valid Haskell

                -- sequence [f,g] x = [f x,g x]


                This is not a valid Haskell in general because of the typing issues, but in our specific case it does give rise to one more valid definition, which also does seem to follow the inner logic of it nicely,



                between a z = -- foldr1 ($) . sequence [(&&).(a <), (< z)] -- not OK
                = foldr1 (&&) . sequence [(a <), (< z)] -- OK
                = and . sequence [(a <), (> z)]


                because (a <) and (> z) have the same type.






                share|improve this answer


























                  2












                  2








                  2







                  By operator sections transformation,



                  between min max x = (min < x) && (x < max)
                  = ((&&) . (min <)) x ((< max) x)


                  Now this fits a pattern for S-combinator, S f g x = (f x) (g x). There are many ways of encoding it in Haskell, but the main two are via Applicative and via Arrows:



                      _S f g x = (f x) (g x)
                  = (f <*> g) x
                  = uncurry id . (f &&& g) $ x


                  The second gives us



                  between a z = uncurry (&&) . ((a <) &&& (< z))


                  And the first, even more fitting



                  between a z = (&&) <$> (a <) <*> (< z)
                  = liftA2 (&&) (a <) (< z)
                  = (a <) <^(&&)^> (< z) -- nice and visual

                  (<^) = flip (<$>)
                  (^>) = (<*>)


                  But we could also fiddle with other combinators, with much less satisfactory results though,



                      _S f g x = f x (g x)
                  = flip f (g x) x
                  = (flip f . g) x x
                  = join (flip f <$> g) x
                  = (flip f =<< g) x


                  or



                               = (f x . g) x
                  = (. g) (f x) x
                  = ((. g) =<< f) x


                  which illustrates nicely the dangers of pointlessness in the pursuit of the pointfree.



                  There's one more possibility that makes sense (syntactically), which is



                      _S f g x = (f x) (g x)
                  -- = foldr1 ($) . sequence [f,g] $ x -- not valid Haskell

                  -- sequence [f,g] x = [f x,g x]


                  This is not a valid Haskell in general because of the typing issues, but in our specific case it does give rise to one more valid definition, which also does seem to follow the inner logic of it nicely,



                  between a z = -- foldr1 ($) . sequence [(&&).(a <), (< z)] -- not OK
                  = foldr1 (&&) . sequence [(a <), (< z)] -- OK
                  = and . sequence [(a <), (> z)]


                  because (a <) and (> z) have the same type.






                  share|improve this answer













                  By operator sections transformation,



                  between min max x = (min < x) && (x < max)
                  = ((&&) . (min <)) x ((< max) x)


                  Now this fits a pattern for S-combinator, S f g x = (f x) (g x). There are many ways of encoding it in Haskell, but the main two are via Applicative and via Arrows:



                      _S f g x = (f x) (g x)
                  = (f <*> g) x
                  = uncurry id . (f &&& g) $ x


                  The second gives us



                  between a z = uncurry (&&) . ((a <) &&& (< z))


                  And the first, even more fitting



                  between a z = (&&) <$> (a <) <*> (< z)
                  = liftA2 (&&) (a <) (< z)
                  = (a <) <^(&&)^> (< z) -- nice and visual

                  (<^) = flip (<$>)
                  (^>) = (<*>)


                  But we could also fiddle with other combinators, with much less satisfactory results though,



                      _S f g x = f x (g x)
                  = flip f (g x) x
                  = (flip f . g) x x
                  = join (flip f <$> g) x
                  = (flip f =<< g) x


                  or



                               = (f x . g) x
                  = (. g) (f x) x
                  = ((. g) =<< f) x


                  which illustrates nicely the dangers of pointlessness in the pursuit of the pointfree.



                  There's one more possibility that makes sense (syntactically), which is



                      _S f g x = (f x) (g x)
                  -- = foldr1 ($) . sequence [f,g] $ x -- not valid Haskell

                  -- sequence [f,g] x = [f x,g x]


                  This is not a valid Haskell in general because of the typing issues, but in our specific case it does give rise to one more valid definition, which also does seem to follow the inner logic of it nicely,



                  between a z = -- foldr1 ($) . sequence [(&&).(a <), (< z)] -- not OK
                  = foldr1 (&&) . sequence [(a <), (< z)] -- OK
                  = and . sequence [(a <), (> z)]


                  because (a <) and (> z) have the same type.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 23 '18 at 10:16









                  Will NessWill Ness

                  45.5k468124




                  45.5k468124






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53391699%2fhow-to-write-this-function-in-point-free-style%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

                      ComboBox Display Member on multiple fields

                      Is it possible to collect Nectar points via Trainline?