У меня есть следующий код
newtype State s a = State { runState :: s -> (s,a) }
evalState :: State s a -> s -> a
evalState sa s = snd $ runState sa s
instance Functor (State s) where
fmap f sa = State $ \s ->
let (s',a) = runState sa s in
(s',f a)
instance Applicative (State s) where
pure a = State $ \s -> (s,a)
sf <*> sa = State $ \s ->
let (s',f) = runState sf s
(s'',a) = runState sa s' in
(s'', f a)
instance Monad (State s) where
sa >>= k = State $ \s ->
let (s',a) = runState sa s in
runState (k a) s'
get :: State s s
get = State $ \s -> (s,s)
set :: s -> State s ()
set s = State $ \_ -> (s,())
bar (acc,n) = if n <= 0
then return ()
else
set (n*acc,n-1)
f x = factLoop
factLoop = get >>= bar >>= f
И
runState factLoop (1,7)
дает ((5040,0),())
Я пытаюсь написать функцию
factLoop = get >>= bar >>= f
используя нотацию do
Я пытался
factLoop' = do
(x,y) <- get
h <- bar (x,y)
return ( f h)
Но это не дает правильного типа, который должен быть State (Int, Int) ()
Есть идеи?
Спасибо!