0

我正在尝试在 Haskell 中为 Brainf*ck 编写解释器。但我收到类型错误。

下面只显示代码的相关部分:

--my own defined data type
data BFState = BFState {
  program :: String,      -- program being interpreted
  input :: String,  -- input for the program
  memory :: [Word8],     -- memory is a list of 8bit representation of INTs since only least 8 bits are read
  prog_pointer :: Int,         -- current pointer in the program STRING (pc)
  mem_pointer :: Int         -- current pointer in the memory LIST (pos)
}

--Initialise the BFState before the Intepreter runs the inputted BF code.
initState :: String -> String -> Int -> BFState
initState program input memSize = BFState program input (take memSize (repeat 0)) 0 0

--Helper function for the main function (bf program input)
run state = if isEnd state
            then return () --when reached the end, just return
            else do newState <- (iterateBF state) --update to new state after iterating one BF comand
                    run newState --run with new state

--the main function
bf program input = run (initState program input 10000)

现在,我收到一个类型错误:

Couldn't match expected type `String'
            with actual type `BFState -> String'
In the first argument of `initState', namely `program'
In the first argument of `run', namely
  `(initState program input 10000)'
In the expression: run (initState program input 10000)

编译器说的时候指的是什么actual type 'BFState -> String'

----对于sepp2k

iterateBF :: BFState -> IO BFState
iterateBF state = case (program state !! prog_pointer state) of
    '+' -> return state {memory = setMem state ((getMem state) + 1), prog_pointer = nextPP state}
    '-' -> return state {memory = setMem state ((getMem state) - 1), prog_pointer = nextPP state}
    '>' -> return state {mem_pointer = (mem_pointer state) + 1, prog_pointer = nextPP state}
    '<' -> return state {mem_pointer = (mem_pointer state) - 1, prog_pointer = nextPP state}
    '[' -> return state {prog_pointer = prog_pointer'} where
            prog_pointer' = findClosingBrace (program state) (prog_pointer state)
    ']' -> return state {prog_pointer = prog_pointer'} where
            prog_pointer' = findOpeningBrace (program state) (prog_pointer state)
    ',' -> let inputVal = fromIntegral (fromEnum (head (input state))) in 
           return state {memory = setMem state inputVal, prog_pointer = nextPP state, input = drop 1 (input state)}
    '.' -> do hPutChar stdout (chr (fromEnum $ getMem state))
              hFlush stdout
              return state { prog_pointer = prog_pointer state}
    otherwise -> return (state {prog_pointer = nextPP state}) --ignore other characters

--check if we are at the end of the program
isEnd :: BFState -> Bool
isEnd state = (prog_pointer state) >= length (program state)
4

2 回答 2

4

那是因为“程序”的类型(initState 函数的第一个参数)不是字符串。它实际上是 BFState -> String,您可以通过在 ghci 提示符中输入 ":t program" 来验证(当然,不带引号)。

于 2012-12-01T22:13:57.343 回答
1

program应该有类型(因为这就是类型签名所说的应该是),但实际上类型,因为这是 . 的第一个参数的类型。StringinitStateBFState -> Stringbf

如果您为 提供显式类型签名bf,您可能会发现代码中的实际错误是您bf使用类型的第一个参数调用的某个地方BFState -> String

于 2012-12-01T22:06:31.107 回答