You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 → brainfuckRec
  • Brainfuck → 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 08:28:11