1

Ich schreibe gerade einen kleinen Compiler für einen Kurs, den ich mache. Also fing ich an, diesen Monad Transformer zu schreiben, um die Typchecking zu handhaben, aber ich bekam einen sehr kryptischen Typfehler. Etwas mit funktionalen Abhängigkeiten, die ich nicht wirklich gut kenne. Ein kleiner Auszug aus dem Programm, das die Fehler reproduzieren kann:Was bedeutet dieser Tippfehler?

import Control.Monad.RWS.Lazy 
import qualified Data.Map as M 
import Control.Applicative 

--Placeholders for other data types. 
data TypeError = TypeError 
data Ident = Ident String 
data Type = Type 

type Typer a = RWS FunctionTable [TypeError] IdentTable a 

type FunctionTable = M.Map Ident Type 

type IdentTable = [M.Map Ident Type] 

emptyIdents :: IdentTable 
emptyIdents = [] 

getIdent :: Ident -> Typer (Maybe Type) 
getIdent id = getIdent' id <$> get 

getIdent' :: Ident -> IdentTable -> Maybe Type 
getIdent' _ [] = Nothing 
getIdent' id (x:xs) = 
    case M.lookup id x of 
    Just t -> Just t 
    Nothing -> getIdent' id xs 

putIdent :: Ident -> Type -> Typer() 
putIdent id ty = modify $ \xs -> case xs of 
    [] -> [M.singleton id ty] 
    (x:xs) -> (M.insert id ty x) : xs 

scopeEnter :: Typer() 
scopeEnter = modify $ \ids -> emptyIdents : ids 

scopeExit :: Typer() 
scopeExit = modify tail 

Und die eigentliche Nachricht:

[1 of 1] Compiling Main    (ErrorExample.hs, interpreted) 

ErrorExample.hs:30:22: 
    Couldn't match type `M.Map Ident Type' with `Type' 
    When using functional dependencies to combine 
     MonadState 
     [[M.Map Ident Type]] 
     (RWST 
      (M.Map Ident Type) 
      [TypeError] 
      [M.Map Ident Type] 
      transformers-0.2.2.0:Data.Functor.Identity.Identity), 
     arising from a use of `modify' at ErrorExample.hs:35:18-23 
     MonadState 
     [M.Map Ident Type] 
     (RWST 
      (M.Map Ident Type) 
      [TypeError] 
      [M.Map Ident Type] 
      transformers-0.2.2.0:Data.Functor.Identity.Identity), 
     arising from a use of `modify' at ErrorExample.hs:30:22-27 
    In the expression: modify 
    In the expression: 
     modify 
     $ \ xs 
      -> case xs of { 
       [] -> [...] 
       (x : xs) -> (M.insert id ty x) : xs } 

ErrorExample.hs:30:22: 
    Couldn't match type `[]' with `M.Map Ident' 
    When using functional dependencies to combine 
     MonadState 
     [[M.Map Ident Type]] 
     (RWST 
      (M.Map Ident Type) 
      [TypeError] 
      [M.Map Ident Type] 
      transformers-0.2.2.0:Data.Functor.Identity.Identity), 
     arising from a use of `modify' at ErrorExample.hs:35:18-23 
     MonadState 
     [M.Map Ident Type] 
     (RWST 
      (M.Map Ident Type) 
      [TypeError] 
      [M.Map Ident Type] 
      transformers-0.2.2.0:Data.Functor.Identity.Identity), 
     arising from a use of `modify' at ErrorExample.hs:30:22-27 
    In the expression: modify 
    In the expression: 
     modify 
     $ \ xs 
      -> case xs of { 
       [] -> [...] 
       (x : xs) -> (M.insert id ty x) : xs } 

ErrorExample.hs:35:18: 
    Couldn't match type `Type' with `M.Map Ident Type' 
    When using functional dependencies to combine 
     MonadState s (RWST r w s m), 
     arising from the dependency `m -> s' 
     in the instance declaration in `Control.Monad.State.Class' 
     MonadState 
     [[M.Map Ident Type]] 
     (RWST 
      (M.Map Ident Type) 
      [TypeError] 
      [M.Map Ident Type] 
      transformers-0.2.2.0:Data.Functor.Identity.Identity), 
     arising from a use of `modify' at ErrorExample.hs:35:18-23 
    In the expression: modify 
    In the expression: modify $ \ ids -> emptyIdents : ids 

ErrorExample.hs:35:18: 
    Couldn't match type `M.Map Ident' with `[]' 
    When using functional dependencies to combine 
     MonadState s (RWST r w s m), 
     arising from the dependency `m -> s' 
     in the instance declaration in `Control.Monad.State.Class' 
     MonadState 
     [[M.Map Ident Type]] 
     (RWST 
      (M.Map Ident Type) 
      [TypeError] 
      [M.Map Ident Type] 
      transformers-0.2.2.0:Data.Functor.Identity.Identity), 
     arising from a use of `modify' at ErrorExample.hs:35:18-23 
    In the expression: modify 
    In the expression: modify $ \ ids -> emptyIdents : ids 
Failed, modules loaded: none. 
Leaving GHCi. 

Antwort

4

Es ist eine sehr schlechte Fehlermeldung. Die Ursache liegt an einem Typ, der in State nicht übereinstimmt. Ihr Code versucht, [M.Map Ident Type] und [[M.Map Ident Type]] zu mischen.

Wenn Sie manuell die emptyIdents rufen in scopeEnter Inline sieht es wie folgt aus:

scopeEnter :: Typer() 
scopeEnter = modify $ \ids -> [] : ids 

... die viel Sinn nicht für [M.Map Ident Type] machen. Vergleichen Sie das mit der Version, die typecheck:

scopeEnter :: Typer() 
scopeEnter = modify $ \ids -> M.empty : ids