1

저는 현재 취하고있는 과정을위한 작은 컴파일러를 작성하고 있습니다. 그래서 typechecking을 처리하기 위해이 모나드 변환기를 작성하기 시작했으나 매우 비밀스러운 형식 오류가 발생했습니다. 기능적 종속성과 관련이 있습니다. 실제로는 잘 모릅니다. 오류를 재현 할 수있는 프로그램에서 작은 발췌 :이 형식 검사 오류는 무엇을 의미합니까?

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 

그리고 실제 메시지 :

[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. 

답변

4

그것은 매우 잘못된 오류 메시지입니다. 원인은 주에서 유형이 일치하지 않기 때문입니다. 귀하의 코드가 [M.Map Ident Type]과 [[M.Map Ident Type]]을 혼합하려고합니다. 수동으로 emptyIdents이 scopeEnter를 호출 인라인 경우

그것은 다음과 같습니다 [M.Map Ident Type] 훨씬 이해가되지 않습니다

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

을 .... 형식 검사를 수행하는 버전과 비교하십시오.

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