I recently had the idea to build a monad that counted the number of binds a computation goes through. I came up with the following:
newtype K a = K { runK :: Int -> (a, Int) }
instance Functor K where
fmap f k = K $ \s ->
let (iv, s') = runK k s
in (f iv, s')
instance Applicative K where
pure x = K $ \s -> (x, s)
f <*> b = K $ \s ->
let (f', s') = runK f s
(ih, s'') = runK b s'
in (f' ih, s'')
instance Monad K where
return x = K $ \s -> (x, s)
a >>= f = K $ \s ->
let (iv, s') = runK a s
in runK (f iv) (s' + 1)
which I later realized was just the State
monad and not very interesting. Then, I had the idea to try to build an arrow that counted "connections". Here I am a bit stumped.
newtype L a b = L { runL :: Int -> (a -> b, Int) }
instance Category L where
id = arr Prelude.id
b . a = L $ \s ->
let (f1, s') = runL a s
(f2, s'') = runL b s'
in (f2 Prelude.. f1, s'' + 1)
instance Arrow L where
arr f = L $ \s -> (f, s + 1)
first a = L $ \s ->
let (f1, s') = runL a s
in (\(x, y) -> (f1 x, y), s')
I came up with the above which would count the number of connections, but doesn't count the number of connections a computation goes through. Suggestions?
s''+1
instead ofs''+s'
? The asymmetry just stands out as odd. – ErikRMonad
instance forK
is not law-abiding. Counting binds can't be, because some laws have a different number of binds on the two sides of the equation, e.g.return x >>= f = f x
. Counting uses of.
in aCategory
has a similar problem, sinceid . f = f
is an equation. – Daniel Wagner