Reputation: 95
It is only a skeleton of program. I have main function, that
State [Dec] [Dec]
mainCon = do
acc <- get
put []
modify $ (++) [some func]
return acc
On one stage I call function:
foldlWithKey'
(\list' key' val' ->
if (...)
then
(Control.Monad.State.modify $ (Prelude.++) [elem]) >>
some code
: list')
else
(Control.Monad.State.modify $ (Prelude.++) []) >>
some code
: list')
)
[]
(map')
and want to modify State in mainCon, but continue traverse map'. The error is:
No instance for (MonadState [Dec] [])
arising from a use of ‘Control.Monad.State.modify’
In the expression: Control.Monad.State.modify
[Dec] from Template Haskell. How can I simply solve this problem?
Upvotes: 0
Views: 134
Reputation: 52029
Conceptually the problem is that the
first argument passed to foldWithKey'
must be a pure function,
but when you use modify
you are creating a stateful computation,
not a pure function.
Apparently you are trying to iterate through a hashmap while
maintaining some state during the traversal. foldWithKey'
already gives you that state - it's the first parameter to
the accumulation function:
v-- current state
foldlWithKey' :: (a -> k -> v -> a) -> a -> HashMap k v -> a
new state --^ ^-- initial ^-- final
state state
The accumulation function takes the current state, a key and a value
and returns an updated state. Then if you give foldWithKey'
an initial
state it will return the final state.
Here's an example using foldWithKey
which is the same as
foldWithKey'
except that the arguments are in a slightly
different order.
The functionevenOdds
returns two lists - one containing
the keys which have even values and those which have odd values.
The state is the pair (even,odds)
, and the accumulation function go
returns the updated state based on the current key and value.
{-# LANGUAGE NoMonomorphismRestriction #-}
import qualified Data.HashMap as H
myMap = H.fromList [ ("a",1), ("b",2), ("c",3), ("d",4) ]
evenOdds :: ([String],[String])
evenOdds = H.foldWithKey go ([],[]) myMap
where go :: String -> Int -> ([String],[String]) -> ([String],[String])
go k a (evens,odds) =
if even a then ( evens ++ [k], odds)
else ( evens , odds ++ [k] )
Upvotes: 1