Introduce a bidirectional counter in functional programming?

I am trying to wrap my head in some of the basics of functional programming.

So, using a higher order function, I can create a counter that can increment:

function counter( start ) {
  var count = start;
  return function() {
    return ++count;
  }
}

var myCounter = counter( 2 );
myCounter();
myCounter();

However, what would be the correct (from the point of view of functional programming) way to implement a bi-directional counter? I came up with the following, but it seems to me that this is too cheap for me:

function bicounter( start ) {
  var count = start;
  var mutate = function(amount) {
    return function() { count += amount; }
  };
  return {
    increment: mutate(1),
    decrement: mutate(-1)
  }
}

var myCounter = bicounter( 2 );
myCounter.increment();
myCounter.decrement();
+4
source share
1 answer

Functional programming literally means "programming with functions." Here we are talking about a mathematical function and not a subroutine . What's the difference?

  • ( Ackermann):

    Ackerman function

    (.. ). : . .

  • , :

    function A(m, n) {
        var stack = [], exit;
    
        do {
            if (m > 0) {
                m = m - 1;
    
                while (n > 0) {
                    stack.push(m);
                    n = n - 1;
                }
    
                n = 1;
            } else {
                m = stack.pop();
                n = n + 1;
            }
        } while (m !== exit);
    
        return n;
    }
    

    . , , m, n stack. , , , .

counter:

function counter(count) {
    return function () {
        return ++count;
    };
}

var countup = counter(0);

alert(countup()); // 1
alert(countup()); // 2
alert(countup()); // 3
Hide result

? , , . counter . , (.. ) .

: , - , JavaScript . , . .

, -. , counter, , -. , , counter. , . . - .

, , ?

. . ? , . .

, , , , Number, , . , , { count: Number } (.. count, Number), counter. , :

var counter = { count: 5 }; // counter :: Counter

counter :: Counter "counter - counter".

:

// Counter :: Number -> Counter

function Counter(count) {
    return { count: count };
}

var counter = Counter(5); // counter :: Counter

, counter ( Number -> Counter, "Number counter" ), counter ( { count: Number }). . , .

, :

// count :: Counter -> Number

function count(counter) {
    return counter.count;
}

. , counter . , Number counter (.. n counter c counter, c n count ).

, counter Number . counter.

, counter increment. . . counter? , counter. . , :

// increment :: Counter -> Counter

function increment(counter) {
    return Counter(count(counter) + 1);
}

, decrement:

// decrement :: Counter -> Counter

function decrement(counter) {
    return Counter(count(counter) - 1);
}

, Number counter, increment decrement c c + 1 c - 1 . , - .

, ?

, . , , . , , ?

function bicounter(count) {
    return {
        increment: update(+1),
        decrement: update(-1)
    };

    function update(amount) {
        return function () {
            return count += amount;
        };
    }
}

var counter = bicounter(0);
alert(counter.increment()); // 1
alert(counter.decrement()); // 0
Hide result

, , , State. Haskell , JavaScript:

import Control.Monad.State

type Counter = Int

counter :: Counter
counter = 0

increment = modify (+1)
decrement = modify (subtract 1)

alert = get >>= (liftIO . print)

program = do
    increment
    alert
    decrement
    alert

main = evalStateT program counter

Haskell. , ? . , Haskell.

+6

All Articles