Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell代数数据类型模式匹配_Haskell_Pattern Matching_Algebraic Data Types - Fatal编程技术网

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的解决方案。所以你们真的很接近