2014-10-17 9 views
0

Я пытаюсь определить государственное казенное монады» государства в Haskellопределения «монады, которая подсчитывает Гец, Кладет, Bind и возвращает сделанные на нем

newtype State' s a = State' { runState' :: (s, Counts) -> (a, s, Counts) } 

Графы отслеживает количество привязок, возвращается получает и положить сделал на нем

data Counts = Counts { 
binds :: Int, 
returns :: Int, 
gets :: Int, 
puts :: Int 
} deriving (Eq, Show) 

instance Monoid Counts where 
mempty = Counts 0 0 0 0 
mappend (Counts x1 x2 x3 x4) (Counts y1 y2 y3 y4) = Counts (x1+y1) (x2+y2) (x3+y3) (x4+y4) 

мне удалось определить возвращение и >> = для этой новой монады как таковой

return x = State' f 
      where f = \(s, count) -> (x,s,count <> oneReturn 

st >>= k = State' (\(s, count) -> let (x,s',count') = runState' st (s, count) in runState' (k x) (s',count' <> oneBind)) 

H owever, я не могу определить get и put для этого состояния.
Им нужно сделать то же самое, что и put и get of State, однако им также необходимо увеличивать счет на onePut и oneGet (константы, содержащие один get и one put)

Может ли кто-нибудь помочь мне разобраться, как лучше всего определить, как получить и поставить для государства?

+2

Вы не можете подсчитать количество привязок и возвращает, удовлетворяя законам монады. 'm >> = return' должен быть равен' m' в соответствии с законами. –

+0

@TomEllis хорошая точка, но что такое «равно»? Free monad 'm >> = return' также не создает структуру, равную' m', добавляет только «слои». –

+0

'Control.Monad.Free' не добавляет слой, но' operating' делает. Это одна из причин, почему я предпочитаю «Свободный», хотя, как вы говорите, не совсем ясно, что жесткая интерпретация равенства обязательно полезна во всех случаях. –

ответ

2

Кажется get как return, но поставляет s вместо x.

get = State' $ \(s, count) -> (s, s, count <> oneGet) 

Тогда put также как и return, но устанавливает новый s.

put s' = State' $ \(s, count) -> ((), s', count <> onePut) 
+0

Вы забыли поместить скобки вокруг своей функции lamda, кроме того, вы полностью правы. – LordofTurtles

+0

Возможно, вы могли бы превратить ее в «новый тип», реализующий «MonadState» (либо в виде монады, либо монада-трансформатора), чтобы вы могли использовать там, где кто-то использует государственную монаду. –

+0

@LordofTurtles Я не знаю, что вы имеете в виду. '$' достаточно, а выражение справа от '->' является телом лямбда. –