2016-05-15 50 views
0

它只是程序的一個框架。我的主要功能,即從另一個函數使用State.modify

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,而是繼續移圖」。錯誤是:

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

'foldWithKey''的類型簽名是什麼? – ErikR

+0

@ErikR foldlWithKey'::(a - > k - > v - > a) - > a - > HashMap k v - > a – Ivan

回答

1

概念上的問題是,傳遞給foldWithKey'的 第一個參數必須是一個純函數, 但是當你用modify要創建一個有狀態計算, 不是純粹的功能。

顯然你正試圖迭代通過散列圖,而 在遍歷過程中保持一些狀態。 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]) 
相關問題