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

Haskell函数checkDirecRio非穷尽模式问题求助

解决Haskell中checkDirecRio函数的非穷尽模式问题

问题描述

你的checkDirecRio函数编译通过,但调用时触发Non-exhaustive patterns错误,函数需求为:验证相邻Rio的方向,若存在相邻Rio方向相反则返回True,所有相邻Rio方向均相同(或无相邻Rio)则返回False。

数据结构定义

type Velocidade = Int

data Mapa =
  Mapa Largura [(Terreno, [Obstaculo])]
  deriving (Show, Read, Eq)

data Terreno
  = Rio Velocidade
  | Estrada Velocidade
  | Relva
  deriving (Show, Read, Eq)

data Obstaculo
  = Nenhum -- ^ nothing
  | Tronco -- ^ wood who can only in Rio being
  | Carro -- ^ car who can only in Estrada being
  | Arvore -- ^ tree who can only in Relva being
  deriving (Show, Read, Eq)

原始出错代码

checkDirecRio :: Mapa -> Bool
checkDirecRio (Mapa _ []) = True
checkDirecRio (Mapa larg ((Rio x, _) : (_,_)  : t)) = checkDirecRio (Mapa larg t)
checkDirecRio (Mapa larg ((Rio x, _) : (Rio y, _) : t)) | ((x > 0 && y < 0) || (x < 0 && y > 0)) = True
                                                        | otherwise = checkDirecRio (Mapa larg t)

问题根源

函数未覆盖所有输入场景,遗漏了:

  • 列表仅剩单个元素的情况(无论地形类型)
  • 第一个元素不是Rio的情况(比如开头是Estrada或Relva)
  • 处理相邻Rio时跳过了连续多Rio的检查(比如[Rio x, Rio y, Rio z]会直接跳到z,忽略y和z的相邻检查)

修复后的代码

checkDirecRio :: Mapa -> Bool
checkDirecRio (Mapa _ []) = False  -- 无相邻地形,不存在相反方向的Rio
checkDirecRio (Mapa larg (_ : [])) = False  -- 单个元素,无相邻地形可检查
checkDirecRio (Mapa larg ((Rio x, _) : (Rio y, _) : t))
  | (x > 0 && y < 0) || (x < 0 && y > 0) = True  -- 发现方向相反的相邻Rio,直接返回True
  | otherwise = checkDirecRio (Mapa larg ((Rio y, _) : t))  -- 保留第二个Rio,继续检查后续相邻对
checkDirecRio (Mapa larg (_ : t)) = checkDirecRio (Mapa larg t)  -- 第一个元素非Rio,跳过并检查剩余列表

代码逻辑说明

  1. 空列表/单个元素:直接返回False,因为没有相邻地形可以验证。
  2. 相邻两个都是Rio:
    • 若速度符号相反(方向相反),立即返回True,满足需求。
    • 若方向相同,将第二个Rio作为新的起始元素,继续检查后续列表,避免遗漏连续Rio的相邻检查。
  3. 第一个元素非Rio:跳过当前元素,递归检查剩余列表。

内容的提问来源于stack exchange,提问作者Filipe Chehab

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 22:05:11