Haskell Brainfuck解释器类型签名错误排查与修复求助
Haskell Brainfuck解释器类型签名错误排查与修复
问题描述
作为Haskell新手编写简单的Brainfuck解释器时,在BrainfuckRec :: [Int] -> Int -> [Char] -> [(Int, Int)] -> Int -> IO ()类型签名处收到以下错误:
- Invalid type signature: BrainfuckRec :: ...
- A type signature should be of form
<variables> :: <type>
即使多次修改代码,该错误仍然存在。
错误成因
Haskell有严格的命名规则:
- 函数名必须以小写字母开头
- 大写开头的标识符会被编译器识别为类型或数据构造器,而非函数
你的代码中BrainfuckRec和Brainfuck均为大写开头,编译器将它们视为类型而非函数,因此类型签名的语法检查失败——类型签名仅能为函数或变量指定类型,不能为类型本身重复声明类型。
修复方案
将所有大写开头的函数名改为小写开头,同时修改代码中所有调用这些函数的位置:
BrainfuckRec→brainfuckRecBrainfuck→brainfuck
完整修复代码
import Text.Read (readMaybe) import Data.List (findIndex) import Data.Char (chr, ord) -- 匹配循环括号 findPairs :: [Int] -> [Char] -> [(Int, Int)] -> Int -> [(Int, Int)] findPairs [] [] pairs _ = pairs findPairs [] (']':_) _ idx = error ("Unmatched ']' at " ++ show idx) findPairs stack [] pairs idx = error ("Unmatched '[' at " ++ show idx) findPairs stack (x:xs) pairs idx | x == '[' = findPairs (idx : stack) xs pairs (idx + 1) | x == ']' = case stack of [] -> error ("Unmatched ']' at " ++ show idx) (s:st) -> findPairs st xs ((s, idx) : pairs) (idx + 1) | otherwise = findPairs stack xs pairs (idx + 1) -- 递归式Brainfuck解释器 brainfuckRec :: [Int] -> Int -> [Char] -> [(Int, Int)] -> Int -> IO () brainfuckRec arr ptr code pairs current = if current == length code then putStrLn "\n\n<Program terminated>" else case code !! current of '+' -> brainfuckRec ((take ptr arr) ++ [((arr !! ptr) + 1) `mod` 128] ++ drop (ptr + 1) arr) ptr code pairs (current + 1) '-' -> brainfuckRec ((take ptr arr) ++ [if arr !! ptr == 0 then 127 else ((arr !! ptr) - 1) `mod` 128] ++ drop (ptr + 1) arr) ptr code pairs (current + 1) '<' -> brainfuckRec arr (if ptr > 0 then ptr - 1 else 0) code pairs (current + 1) '>' -> brainfuckRec (if ptr == length arr - 1 then arr ++ [0] else arr) (ptr + 1) code pairs (current + 1) '[' -> case findIndex ((== current) . snd) pairs of Just idx -> brainfuckRec arr ptr code pairs (if arr !! ptr == 0 then fst (pairs !! idx) else current + 1) Nothing -> error $ "Unmatched '[' at position " ++ show current ']' -> case findIndex ((== current) . fst) pairs of Just idx -> brainfuckRec arr ptr code pairs (if arr !! ptr /= 0 then snd (pairs !! idx) else current + 1) Nothing -> error $ "Unmatched ']' at position " ++ show current '.' -> do putChar (chr (arr !! ptr)) brainfuckRec arr ptr code pairs (current + 1) ',' -> getLine >>= \input -> let temp = case parseInt input of Just x -> if x >= 0 && x < 128 then x else error "Invalid ASCII value!" Nothing -> ord (head input) in brainfuckRec ((take ptr arr) ++ [temp] ++ drop (ptr + 1) arr) ptr code pairs (current + 1) -- 主Brainfuck解释器入口 brainfuck :: String -> IO () brainfuck inputFile = do code <- readFile inputFile let pairs = findPairs [] code [] 0 brainfuckRec [0] 0 code pairs 0 -- 解析整数输入 parseInt :: [Char] -> Maybe Int parseInt = readMaybe
内容的提问来源于stack exchange,提问作者Victor PISLARU
相关产品推荐
相关产品推荐

