Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8429759
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 10, 20262026-06-10T05:25:32+00:00 2026-06-10T05:25:32+00:00

In the comments of the question Tacit function composition in Haskell , people mentioned

  • 0

In the comments of the question Tacit function composition in Haskell, people mentioned making a Num instance for a -> r, so I thought I’d play with using function notation to represent multiplication:

{-# LANGUAGE TypeFamilies #-}
import Control.Applicative

instance Show (a->r) where   -- not needed in recent GHC versions
  show f = " a function "

instance Eq (a->r) where     -- not needed in recent GHC versions
  f == g = error "sorry, Haskell, I lied, I can't really compare functions for equality"

instance (Num r,a~r) => Num (a -> r) where
  (+) = liftA2 (+)
  (-) = liftA2 (-)
  (*) = liftA2 (*)
  abs = liftA abs
  negate = liftA negate
  signum = liftA signum
  fromInteger a = (fromInteger a *)

Note that the fromInteger definition means I can write 3 4 which evaluates to 12, and 7 (2+8) is 70, just as you’d hope.

Then it all goes wonderfully, entertainingly weird! Please explain this wierdness if you can:

*Main> 1 2 3
18
*Main> 1 2 4
32
*Main> 1 2 5
50
*Main> 2 2 3
36
*Main> 2 2 4
64
*Main> 2 2 5
100
*Main> (2 3) (5 2)
600

[Edit: used Applicative instead of Monad because Applicative is great generally, but it doesn’t make much difference at all to the code.]

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-10T05:25:34+00:00Added an answer on June 10, 2026 at 5:25 am

    In an expression like 2 3 4 with your instances, both 2 and 3 are functions. So 2 is actually (2 *) and has a type Num a => a -> a. 3 is the same. 2 3 is then (2 *) (3 *) which is the same as 2 * (3 *). By your instance, this is liftM2 (*) 2 (3 *) which is then liftM2 (*) (2 *) (3 *). Now this expression works without any of your instances.

    So what does this mean? Well, liftM2 for functions is a sort of double composition. In particular, liftM2 f g h is the same as \ x -> f (g x) (h x). So liftM2 (*) (2 *) (3 *) is then \ x -> (*) ((2 *) x) ((3 *) x). Simplifying a bit, we get: \ x -> (2 * x) * (3 * x). So now we know that 2 3 4 is actually (2 * 4) * (3 * 4).

    Now then, why does liftM2 for functions work this way? Let’s look at the monad instance for (->) r (keep in mind that (->) r is (r ->) but we can’t write type-level operator sections):

    instance Monad ((->) r) where  
        return x = \_ -> x  
        h >>= f = \w -> f (h w) w  
    

    So return is const. >>= is a little weird. I think it’s easier to see this in terms of join. For functions, join works like this:

    join f = \ x -> f x x
    

    That is, it takes a function of two arguments and turns it into a function of one argument by using that argument twice. Simple enough. This definition also makes sense. For functions, join has to turn a function of two arguments into a function of one; the only reasonable way to do this is to use that one argument twice.

    >>= is fmap followed by join. For functions, fmap is just (.). So now >>= is equal to:

    h >>= f = join (f . h)
    

    which is just:

    h >>= f = \ x -> (f . h) x x
    

    now we just get rid of . to get:

    h >>= f = \ x -> f (h x) x
    

    So now that we know how >>= works, we can look at liftM2. liftM2 is defined as follows:

    liftM2 f a b = a >>= \ a' -> b >>= \ b' -> return (f a' b')
    

    We can simply this bit by bit. First, return (f a' b') turns into \ _ -> f a' b'. Combined with the \ b' ->, we get: \ b' _ -> f a' b'. Then b >>= \ b' _ -> f a' b' turns into:

     \ x -> (\ b' _ -> f a' b') (b x) x
    

    since the second x is ignored, we get: \ x -> (\ b' -> f a' b') (b x) which is then reduced to \ x -> f a' (b x). So this leaves us with:

    a >>= \ a' -> \ x -> f a' (b x)
    

    Again, we substitute >>=:

    \ y -> (\ a' x -> f a' (b x)) (a y) y
    

    this reduces to:

     \ y -> f (a y) (b y)
    

    which is exactly what we used as liftM2 earlier!

    Hopefully now the behavior of 2 3 4 makes sense completely.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

This question is similar to Getting Emacs fill-paragraph to play nice with javadoc-like comments
(Update - from comments) Question: Is there any advantage of using one extension method
Per this question (see comments near the bottom), I was wondering if anyone knows
(creating a separate question after comments on this: Javascript redeclared global variable overrides old
Looking at the general trend of comments in my question about Building an Aircraft
This question arose from the discussion in the comments of this answer . First,
My question originates from this question, where one of the comments suggests that a
I have a simple question and answer section on my website that allows comments.
Eric Lippert's comments in this question have left me thoroughly confused. What is the
Inspired by the comments on this question , I'm pretty sure that Java String

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.