Недавно у меня возникла идея построить монаду, которая подсчитывала бы количество привязок, через которые проходит вычисление. Я придумал следующее:
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)
который, как я позже понял, был просто монадой State
и не очень интересен. Затем у меня возникла идея попытаться построить стрелку, которая считала бы «соединения». Тут я немного запутался.
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')
Я придумал вышеприведенное, которое будет подсчитывать количество соединений, но не подсчитывает количество соединений, через которые проходит вычисление. Предложения?
s''+1
вместоs''+s'
? Асимметрия просто выделяется как странная. - person ErikR   schedule 02.06.2016Monad
дляK
не соответствует закону. Подсчет биндов невозможен, потому что некоторые законы имеют разное количество биндов с двух сторон уравнения, например.return x >>= f = f x
. Подсчет использования.
вCategory
имеет аналогичную проблему, посколькуid . f = f
является уравнением. - person Daniel Wagner   schedule 02.06.2016