Is it possible to create a Monad that count the number of instructions?

Strictly speaking, any such "monad" breaks the monad laws and is thus... not a monad. See this previous question for details. In other words - your guess is correct, it is not possible to have such a monad.


As another answer already mentioned, no lawful monad can count just the number of binds. But there is a way to count a related quantity: the number of binds minus the number of returns. This is still useful since it lets you count the number of nontrivial monadic operations.

instance Functor Counter where
    fmap f (Counter n x) = Counter n (f x)

instance Applicative Counter where
    pure = Counter (-1)
    Counter n1 f <*> Counter n2 x = Counter (n1 + n2 + 1) (f x)

instance Monad Counter where
    Counter n1 a >>= f = let Counter n2 b = f a in Counter (n1 + n2 + 1) b
    return = Counter (-1)

Here's some quick justifications for why this is lawful:

-- left identity
return x >>= f = f x
Counter (-1) x >>= f = f x
let Counter n2 b = f x in Counter ((-1) + n2 + 1) b = f x
let Counter n2 b = f x in Counter n2 b = f x
f x = f x

-- right identity
m >>= return = m
Counter n1 a >>= return = Counter n1 a
let Counter n2 b = return a in Counter (n1 + n2 + 1) b = Counter n1 a
let Counter n2 b = Counter (-1) a in Counter (n1 + n2 + 1) b = Counter n1 a
Counter (n1 + (-1) + 1) a = Counter n1 a
Counter n1 a = Counter n1 a

-- associativity
m >>= f >>= g = m >>= \x -> f x >>= g
Counter n1 a >>= f >>= g = Counter n1 a >>= \x -> f x >>= g
(let Counter n2 b = f a in Counter (n1 + n2 + 1) b) >>= g = Counter n1 a >>= \x -> f x >>= g
(let Counter n2 b = f a in Counter (n1 + n2 + 1) b) >>= g = let Counter n2 b = (\x -> f x >>= g) a in Counter (n1 + n2 + 1) b
(let Counter n2 b = f a in Counter (n1 + n2 + 1) b) >>= g = let Counter n2 b = f a >>= g in Counter (n1 + n2 + 1) b
let Counter n2 b = f a in (Counter (n1 + n2 + 1) b >>= g) = let Counter n2 b = f a >>= g in Counter (n1 + n2 + 1) b
let Counter n2 b = f a in (let Counter n3 c = g b in Counter ((n1 + n2 + 1) + n3 + 1) c) = let Counter n2 b = f a >>= g in Counter (n1 + n2 + 1) b
let Counter n2 b = f a in (let Counter n3 c = g b in Counter (n1 + n2 + n3 + 2) c) = let Counter n2 b = f a >>= g in Counter (n1 + n2 + 1) b
let Counter n2 b = f a; Counter n3 c = g b in Counter (n1 + n2 + n3 + 2) c = let Counter n2 b = f a >>= g in Counter (n1 + n2 + 1) b
let Counter n2 b = f a; Counter n3 c = g b in Counter (n1 + n2 + n3 + 2) c = let Counter n2 b = (let Counter n3 c = f a in Counter n3 c) >>= g in Counter (n1 + n2 + 1) b
let Counter n2 b = f a; Counter n3 c = g b in Counter (n1 + n2 + n3 + 2) c = let Counter n2 b = (let Counter n3 c = f a in Counter n3 c >>= g) in Counter (n1 + n2 + 1) b
let Counter n2 b = f a; Counter n3 c = g b in Counter (n1 + n2 + n3 + 2) c = let Counter n2 b = (let Counter n3 c = f a in (let Counter n4 d = g c in Counter (n3 + n4 + 1) d)) in Counter (n1 + n2 + 1) b
let Counter n2 b = f a; Counter n3 c = g b in Counter (n1 + n2 + n3 + 2) c = let Counter n2 b = (let Counter n3 c = f a; Counter n4 d = g c in Counter (n3 + n4 + 1) d) in Counter (n1 + n2 + 1) b
let Counter n2 b = f a; Counter n3 c = g b in Counter (n1 + n2 + n3 + 2) c = let Counter n3 c = f a; Counter n4 d = g c in Counter (n1 + (n3 + n4 + 1) + 1) d
let Counter n2 b = f a; Counter n3 c = g b in Counter (n1 + n2 + n3 + 2) c = let Counter n3 c = f a; Counter n4 d = g c in Counter (n1 + n3 + n4 + 2) d

Tags:

Haskell

Monads