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プロンプトに「:tprogram」と入力することで確認できます(もちろん、引用符は含みません)。

于 2012-12-01T22:13:57.343 に答える
1

program型を持つことが期待さStringれますが(の型シグネチャがinitStateそうあるべきであると言っているため)、実際には型を持っています。BFState -> Stringこれは、の最初の引数の型だからbfです。

に明示的な型シグネチャを指定すると、コードの実際の間違いは、どこかで型の最初の引数を使用しbfて呼び出していることに気付くでしょう。bfBFState -> String

于 2012-12-01T22:06:31.107 に答える