Haskell中如何检查列表元组首元素是否为简单Principal?附代码咨询
问题解答
示例结果解释
- 第一个示例返回
True的原因:输入列表里的所有元组第一个元素都是Name构造的简单主体(示例里的a、b应为Name类型变量,比如a = Name "a",b = Name "b"),完全符合“所有元组首元素为简单主体”的要求。 - 第二个示例返回
False的原因:列表里的元组首元素分别是Quote和Together构造的复合主体,不满足“全为简单主体”的条件,因此返回False。
你的代码问题分析
你写的isSimple代码存在多处错误,完全不符合需求:
- 类型不匹配:需求输入类型是
[(Prin,a)](第二个元素支持任意类型),但你定义的是[(Prin,Int)],强行限制第二个元素必须为Int,失去了泛型性。 - 模式匹配错误:
isSimple (x:xs,y:ys)是匹配元组,而非列表。正确的列表模式匹配应为isSimple [](空列表)和isSimple (head:rest)(列表头加剩余部分)。 - 逻辑完全错误:你写的条件
(x,y) ==(Quote x x ,y)是判断当前元素是否为Quote构造,这和需求完全相反——我们需要判断元素是否为Name构造,且该条件写法本身存在逻辑问题(Quote x x里的x是当前元组首元素,会导致无意义的递归判断)。 - 递归调用错误:
isSimple (xs,ys)传递的是元组,但函数输入应为列表,递归逻辑完全无法执行。
正确实现示例
方法1:辅助函数+all高阶函数
type PName = String data Prin = Name PName | Together Prin Prin | Quote Prin Prin deriving (Eq, Show) -- 辅助函数:判断单个Prin是否为简单主体 isSimplePrin :: Prin -> Bool isSimplePrin (Name _) = True isSimplePrin _ = False -- 需求的check函数 check :: [(Prin,a)] -> Bool check lst = all (\(p, _) -> isSimplePrin p) lst
方法2:递归实现
check :: [(Prin,a)] -> Bool check [] = True -- 空列表默认满足条件 check ((p, _):rest) = isSimplePrin p && check rest where isSimplePrin (Name _) = True isSimplePrin _ = False
内容的提问来源于stack exchange,提问作者Xiong Feng Zhu
相关产品推荐
相关产品推荐

