Haskell代数数据类型模式匹配
我有以下资料:Haskell代数数据类型模式匹配,haskell,pattern-matching,algebraic-data-types,Haskell,Pattern Matching,Algebraic Data Types,我有以下资料: data Alpha a = Beta a [Alpha a] val = Beta 1 [Beta 2 [], Beta 5 [Beta 7 []]] 我试图定义一个函数,它将在Alpha Int类型的val上移动并求和。我想要的方法是提取所有整数,然后对结果列表求和,但我正在努力提取所有整数,因为我不知道如何处理递归 略作尝试: checkAlpha :: Alpha Int -> [Int] checkAlpha (Beta a []) = [a] checkAlp
data Alpha a = Beta a [Alpha a]
val = Beta 1 [Beta 2 [], Beta 5 [Beta 7 []]]
我试图定义一个函数,它将在Alpha Int类型的val上移动并求和。我想要的方法是提取所有整数,然后对结果列表求和,但我正在努力提取所有整数,因为我不知道如何处理递归
略作尝试:
checkAlpha :: Alpha Int -> [Int]
checkAlpha (Beta a []) = [a]
checkAlpha (Beta a b) = [a] ++ (map checkAlpha b)
显然这不太管用,但我看不到解决方案。如果您使用
concatMap :: (a -> [b]) -> [a] -> [b]
而不是map
,它将工作并且足够优雅
您不需要将空列表作为第二个组件进行特殊处理
checkAlpha :: Alpha a -> [a]
checkAlpha (Beta a alphas) = a : concatMap checkAlpha alphas
执行所需操作,并且与参数类型无关。如果使用
concatMap :: (a -> [b]) -> [a] -> [b]
而不是map
,它将工作并且足够优雅
您不需要将空列表作为第二个组件进行特殊处理
checkAlpha :: Alpha a -> [a]
checkAlpha (Beta a alphas) = a : concatMap checkAlpha alphas
做你想要的,并且独立于参数类型。
你可以考虑使用而不是<代码> Alpha < /代码>,它有许多方便的操作:> flatten $ Node 1 [Node 2 [], Node 5 [Node 7 []]]
[1,2,5,7]
您可以考虑使用代替<代码> Alpha < /C> >,它有许多方便的操作:
> flatten $ Node 1 [Node 2 [], Node 5 [Node 7 []]]
[1,2,5,7]
在函数中,
b
具有类型[Alpha Int]
。将checkAlpha
映射到此列表将为您提供[[Int]]]
,但您的签名表明您希望返回[Int]
。这就是为什么必须将列表“折叠”为一个层,即(concat.)。map
也称为concatMap
。最简单的解决方法是在代码中的(
和map checkAlpha b)
之间插入concat$
,以使列表变平一级。然后您注意到第一个子句是第二个子句的一个实例,因为map.[]=[]
。然后将[a]+
替换为a:
,以得到Daniel的解决方案。所以你们真的很接近在函数中,b
具有类型[Alpha Int]
。将checkAlpha
映射到此列表将为您提供[[Int]]]
,但您的签名表明您希望返回[Int]
。这就是为什么必须将列表“折叠”为一个层,即(concat.)。map
也称为concatMap
。最简单的解决方法是在代码中的(
和map checkAlpha b)
之间插入concat$
,以使列表变平一级。然后您注意到第一个子句是第二个子句的一个实例,因为map.[]=[]
。然后将[a]+
替换为a:
,以得到Daniel的解决方案。所以你们真的很接近