它只是程序的骨架。我有主要功能,
State [Dec] [Dec]
mainCon = do
acc <- get
put []
modify $ (++) [some func]
return acc
在一个阶段我调用函数:
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')
并希望在mainCon中修改State,但继续遍历map'。错误是:
No instance for (MonadState [Dec] [])
arising from a use of ‘Control.Monad.State.modify’
In the expression: Control.Monad.State.modify
来自Template Haskell的[Dec]。我怎样才能简单地解决这个问题?
答案 0 :(得分:1)
从概念上讲,问题在于
传递给foldWithKey'
的第一个参数必须是纯函数,
但是当你使用modify
时,你正在创建一个有状态的计算,
不是一个纯粹的功能。
显然你正试图迭代一个hashmap
在遍历期间保持某种状态。 foldWithKey'
已经给你那个状态 - 它是第一个参数
积累功能:
v-- current state
foldlWithKey' :: (a -> k -> v -> a) -> a -> HashMap k v -> a
new state --^ ^-- initial ^-- final
state state
累积功能采用当前状态,键和值
并返回更新的状态。然后,如果你给foldWithKey'
一个首字母
说它将返回最终状态。
以下是使用与foldWithKey
相同的示例
foldWithKey'
除了参数略有不同之外
不同的顺序。
函数evenOdds
返回两个列表 - 一个包含
具有偶数值的键和具有奇数值的键。
状态是对(even,odds)
和累积函数go
根据当前键和值返回更新后的状态。
{-# 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] )