2016-05-15 8 views
0

からState.modifyを使用すると、それはプログラムの骨格のみです。 「別の関数

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の状態を変更したいのですが、トラバースマップを続ける:私は1つのステージで

State [Dec] [Dec] 
mainCon = do 
    acc <- get 
    put [] 
    modify $ (++) [some func] 
    return acc 

が、私は関数を呼び出すことを、主な機能を持っています。エラーは、

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です。どうすればこの問題を解決できますか?

+0

'foldWithKey''の型シグネチャは何ですか? – ErikR

+0

@ErikR foldlWithKey」::( - > K - > V - > A) - > A - >ハッシュマップの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は、2つのリストを返します.1つは の偶数値を持つキーと奇数値を持つキーです。

状態は対(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])