For an assignment for FP we have to write a function that runs a state monadic computation given an initial state, and then returns the computed value and the number of operations counted.
Counts looks like this:
data Counts = Counts {
binds :: Int,
returns :: Int,
gets :: Int,
puts :: Int
} deriving (Eq, Show)
Where oneBind = Counts 1 0 0 0 (for example). There was also an mempty and <*> defined, but I wasn't able to use "mempty" instead of "Counts 0 0 0 0" with initCounts.
The States are defined as:
newtype State' s a = State' { runState' :: (s, Counts) -> (a, s, Counts) }
So far this is what I have got, but I've been stuck at about the same level for a few hours now.
run :: State' s a -> s -> (a, Counts)
run s ns = do
initState <- return ns
initCounts <- return (Counts 0 0 0 0)
newState <- return (runState' s (initState, initCounts))
newCounts <- return (runState' (retCounts newState) (newState, initCounts))
let st = let (a,_,_) = newState
in a
let count = let (c,_,_) = newCounts
in c
return (count)
retCounts :: State' s a -> State' s Counts
retCounts st = State' (\ (s, count) -> (calcCounts st, s, count))
calcCounts :: State' s a -> Counts
calcCounts st = undefined
I assume I have to use pattern matching in calcCounts to somehow actually count all the operators/functions, but right now I'm getting a type matching error:
Assignment4.hs:236:47:
Couldn't match expected type ‘State' (a, s, Counts) a0’
with actual type ‘(a, s, Counts)’
Relevant bindings include
newState :: (a, s, Counts) (bound at Assignment4.hs:235:5)
initState :: s (bound at Assignment4.hs:233:5)
ns :: s (bound at Assignment4.hs:232:7)
s :: State' s a (bound at Assignment4.hs:232:5)
run :: State' s a -> s -> (a, Counts)
(bound at Assignment4.hs:232:1)
In the first argument of ‘retCounts’, namely ‘newState’
In the first argument of ‘runState'’, namely ‘(retCounts newState)’
If I could get any help on how I could solve this type error and some hints to go from here, it would be highly appreciated.
PS: I realize it might be a good idea to rename calcCounts to something like calcFunctions
[EDIT: I'm also getting a different error when I work around this one by supplying a dummy value:
Assignment4.hs:233:5:
No instance for (Monad ((,) a)) arising from a do statement
In a stmt of a 'do' block: initState <- return ns
In the expression:
do { initState <- return ns;
initCounts <- return (Counts 0 0 0 0);
newState <- return (runState' s (initState, initCounts));
newCounts <- return (runState' retCounts (newState, initCounts));
.... }
In an equation for ‘run’:
run s ns
= do { initState <- return ns;
initCounts <- return (Counts 0 0 0 0);
newState <- return (runState' s (initState, initCounts));
.... }
]