title: Couldn't match expected types in Proc Parser
body: <p>I'm trying to write a parser for the Proc language, which is an extended version of the While language. When complete it should be able to take input such as:</p>
  
  <pre><code>"/*fac_loop (p.23)*/\ny:=1;\nwhile !(x=1) do (\n y:=y*x;\n x:=x-1\n)"
  </code></pre>
  
  <p>and produce:</p>
  
  <pre><code>(Comp (Ass "y" (N 1)) (While (Neg (Eq (V "x") (N 1))) (Comp (Ass "y"
         (Mult (V "y") (V "x"))) (Ass "x" (Sub (V "x") (N 1))))))
  </code></pre>
  
  <p>I have been given the grammars for Aexp, Bexp and Stm along with the types of Num, Var, Pname, DecV and DecV which I cannot change. My Haskell code is below:</p>
  
  <pre><code>module SecondAttempt where
  
  import System.IO
  import Control.Monad
  {-# LANGUAGE StandaloneDeriving #-}
  import Text.Megaparsec
  import Text.Megaparsec.String
  import Data.List (intercalate)
  
  
  import Prelude hiding (Num)
  import qualified Prelude (Num)
  
  --- Proc definition
  
  -- S ::= x:=a
  --    | skip
  --    |S1 ;S2
  --    | if b then S1 else S2
  --    | while b do S
  --    | begin Dv Dv S end
  --    | call p
  -- Dv ::= var x := a ; DV | ε
  -- Dp ::= proc p is S ; DP | ε
  
  --- Types
  
  type Num   = Integer
  type Var   = String
  type Pname = String
  type DecV  = [(Var,Aexp)]
  type DecP  = [(Pname,Stm)]
  
  --- Data structures
  
  data Aexp = N Num
            | V Var
            | Mult Aexp Aexp
            | Add Aexp Aexp
            | Sub Aexp Aexp
  
  data Bexp = TRUE
            | FALSE
            | Neg Bexp
            | And Bexp Bexp
            | Le Aexp Aexp
            | Eq Aexp Aexp
  
  data Stm = Skip
            | Ass Var Aexp
            | Comp Stm Stm
            | If Bexp Stm Stm
            | While Bexp Stm
            | Block DecV DecP Stm
            | Call Pname
  
  --- Parser Preliminaries
  
  cr :: Parser [Char]
  cr = many (oneOf "\r\n")
  
  tok :: String -&gt; Parser String
  tok t = string t &lt;* whitespace
  
  whitespace :: Parser ()
  whitespace = many (oneOf " \t") *&gt; pure ()
  
  --- Parser
  
  aexp :: Parser Aexp
  aexp =  N     &lt;$ tok "N" &lt;*&gt; num
      &lt;|&gt; V     &lt;$ tok "V" &lt;*&gt; var
      &lt;|&gt; Mult  &lt;$ tok "Mult" &lt;*&gt; aexp &lt;* tok "*" &lt;*&gt; aexp
      &lt;|&gt; Add   &lt;$ tok "Add" &lt;*&gt; aexp &lt;* tok "+" &lt;*&gt; aexp
      &lt;|&gt; Sub   &lt;$ tok "Sub" &lt;*&gt; aexp &lt;* tok "-" &lt;*&gt; aexp
  
  bexp :: Parser Bexp
  bexp =  TRUE  &lt;$ tok "TRUE"
      &lt;|&gt; FALSE &lt;$ tok "FALSE"
      &lt;|&gt; Neg   &lt;$ tok "Neg" &lt;* tok "!" &lt;*&gt; bexp
      &lt;|&gt; And   &lt;$ tok "And" &lt;*&gt; bexp &lt;* tok "&amp;" &lt;*&gt; bexp
      &lt;|&gt; Le    &lt;$ tok "Le" &lt;*&gt; aexp &lt;* tok "&lt;=" &lt;*&gt; aexp
      &lt;|&gt; Eq    &lt;$ tok "Eq" &lt;*&gt; aexp &lt;* tok "=" &lt;*&gt; aexp
  
  stm :: Parser Stm
  stm =   Ass   &lt;$ tok "Ass" &lt;*&gt; var &lt;* tok ":=" &lt;*&gt; aexp
      &lt;|&gt; Comp  &lt;$ tok "Comp" &lt;*&gt; stm &lt;* tok ";" &lt;*&gt; stm
      &lt;|&gt; Skip  &lt;$ tok "Skip"
      &lt;|&gt; If    &lt;$ tok "If" &lt;*&gt; bexp &lt;* tok "then" &lt;*&gt; stm &lt;* tok "else" &lt;*&gt; stm
      &lt;|&gt; While &lt;$ tok "While" &lt;*&gt; bexp &lt;* tok "do" &lt;*&gt; stm
      &lt;|&gt; Block &lt;$ tok "begin" &lt;*&gt; decv &lt;*&gt; decp &lt;*&gt; stm &lt;* tok "end"
      &lt;|&gt; Call  &lt;$ tok "call" &lt;*&gt; pname
  
  num :: Parser Num
  num = (some (oneOf ['0' .. '9']) &gt;&gt;= return . read) &lt;* whitespace
  
  var :: Parser Var
  var = tok "\"" *&gt; some (noneOf ("\n\r\"")) &lt;* tok "\""
  
  decv :: Parser DecV
  decv = var &lt;* tok ":=" &lt;*&gt; aexp &lt;* tok ";" &lt;*&gt; decv
  
  decp :: Parser DecP
  decp = pname &lt;* tok "is" &lt;*&gt; stm &lt;* tok ";" &lt;*&gt; decp
  
  pname :: Parser Pname
  pname = tok "\"" *&gt; some (noneOf ("\n\r\"")) &lt;* tok "\""
  
  true :: Bool
  true = True
  
  false :: Bool
  false = False
  </code></pre>
  
  <p>I am getting two type errors, one each to do with my decv and decp functions:</p>
  
  <pre><code>Couldn't match type ‘[Char]’ with ‘Aexp -&gt; DecV -&gt; DecV’
      Expected type: ParsecT
                       Dec String Data.Functor.Identity.Identity (Aexp -&gt; `DecV -&gt; DecV)
        Actual type: Parser Var
      In the first argument of ‘(&lt;*)’, namely ‘var’
      In the first argument of ‘(&lt;*&gt;)’, namely ‘var &lt;* tok ":="’
  
  Couldn't match type ‘[Char]’ with ‘Stm -&gt; DecP -&gt; DecP’
      Expected type: ParsecT
                       Dec String Data.Functor.Identity.Identity (Stm -&gt; DecP -&gt; DecP)
        Actual type: Parser Pname
      In the first argument of ‘(&lt;*)’, namely ‘pname’
      In the first argument of ‘(&lt;*&gt;)’, namely ‘pname &lt;* tok "is"’
  </code></pre>
  
  <p>Really not sure how to solve this!</p>