2016-05-15 17 views
0

Es ist nur ein Skelett des Programms. Ich habe Hauptfunktion, dassVerwenden von State.modify aus einer anderen Funktion

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

Auf einer Stufe I Funktion aufrufen:

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') 

und wollen Staat in mainCon ändern, aber weiterhin Traverse Karte‘. Der Fehler lautet:

No instance for (MonadState [Dec] []) 
     arising from a use of ‘Control.Monad.State.modify’ 
    In the expression: Control.Monad.State.modify 

[Dezember] von Vorlage Haskell. Wie kann ich dieses Problem einfach lösen?

+0

Was ist die Typ-Signatur von 'foldWithKey''? – ErikR

+0

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

Antwort

1

Konzeptionell ist das Problem, dass die zuerst foldWithKey' gebene Argument eine reine Funktion, sein muss, aber wenn Sie modify Sie eine Stateful Berechnung erstellen, keine reine Funktion.

Anscheinend versuchen Sie, eine hashmap zu durchlaufen, während einen Zustand während des Durchlaufs beibehalten.

    v-- current state 
foldlWithKey' :: (a -> k -> v -> a) -> a -> HashMap k v -> a 
        new state --^  ^-- initial   ^-- final 
              state    state 

Die Akkumulation Funktion nimmt den aktuellen Zustand, einen Schlüssel und einen Wert und gibt einen aktualisierten Zustand: die Akkumulation zu Funktion es der erste Parameter ist - foldWithKey' bereits gibt Ihnen diesen Zustand. Wenn Sie dann foldWithKey' einen anfänglichen -Status angeben, wird der Endstatus zurückgegeben.

Hier ist ein Beispiel foldWithKey verwendet, die die gleichen wie foldWithKey' Ausnahme ist, dass die Argumente in einer leicht anderen Reihenfolge sind.

Die Funktion evenOdds gibt zwei Listen zurück - eine mit die Schlüssel mit geraden Werten und die mit ungeraden Werten.

Der Staat ist das Paar (even,odds) und die Akkumulationsfunktion go gibt den aktualisierten Zustand basierend auf dem aktuellen Schlüssel und Wert.

{-# 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]) 
Verwandte Themen