Haskell中列表首元素的数据类型模式匹配问题
解决Haskell中M类型的模式匹配问题
嘿,我来帮你搞定这个模式匹配的小问题!你遇到的问题主要是对代数数据类型的构造器匹配逻辑理解有点偏差,咱们一步步来修正。
首先,先明确你的M类型构造器:A是接收一个DataA值作为参数的构造器,B接收DataB,C是无参数构造器。所以在列表模式匹配里,你需要先匹配M的构造器,再处理它的参数。
错误写法的原因
你尝试的(DataA m):rest是错的,因为DataA是DataA类型的构造器,而列表里的元素是M类型,两者类型不匹配,编译器肯定会报错。而(A m):rest其实是正确的模式,但你可能没正确处理m(它是DataA类型,需要提取里面的aInt字段),或者漏掉了递归调用myFunction rest,导致编译失败。
正确的实现方式
下面是完整的可运行代码,我还加了示例辅助函数方便你测试:
data M = A DataA | B DataB | C deriving (Eq, Show) data DataA = DataA {aInt::Int} deriving (Eq, Show) data DataB = DataB {bInt::Int} deriving (Eq, Show) -- 示例辅助函数,你可以换成自己的逻辑 doSomething1 :: Int -> Int doSomething1 x = x * 2 -- 比如把A里的Int翻倍 doSomething2 :: Int -> Int doSomething2 x = x + 5 -- 给B里的Int加5 doSomething3 :: Int doSomething3 = 10 -- C对应的固定值 myFunction :: [M] -> Int myFunction [] = 0 -- 匹配A构造器,取出DataA类型的da,再提取aInt字段传给doSomething1 myFunction (A da:rest) = doSomething1 (aInt da) + myFunction rest -- 匹配B构造器,取出DataB类型的db,提取bInt字段传给doSomething2 myFunction (B db:rest) = doSomething2 (bInt db) + myFunction rest -- 匹配C构造器,直接使用doSomething3的值 myFunction (C:rest) = doSomething3 + myFunction rest
更简洁的模式匹配(可选)
如果你想在模式里直接提取Int值,也可以嵌套匹配构造器:
myFunction (A (DataA num):rest) = doSomething1 num + myFunction rest myFunction (B (DataB num):rest) = doSomething2 num + myFunction rest myFunction (C:rest) = doSomething3 + myFunction rest myFunction [] = 0
这样可以省去调用aInt或bInt的步骤,直接拿到Int值num,代码更紧凑。
测试示例
比如运行:
myFunction [A (DataA 3), B (DataB 4), C]
结果会是3*2 + 4+5 +10 = 6+9+10=25,符合预期。
内容的提问来源于stack exchange,提问作者Sweeney Todd
相关产品推荐
相关产品推荐

