haskell - 我应该如何正确传递列表参数?通过这种方式,解释器给了我预期类型的错误
问题描述
我想在树列表中找到具有最大子节点数的节点。
我尝试将参数传递为 't' ,作为单例 '[t]',作为模式匹配 '(t:ts)',作为 '[Tree t]'。以上都没有奏效。
data Tree a = Void2 | Node2 a [Tree a] deriving (Eq,Show)
degree [Void2] = 0
degree [] = 0
degree (Node2 a t) = max (length t) (maximum (map degree t))
这是口译员给我的错误
Couldn't match expected type ‘[Tree a0]’
with actual type ‘Tree a’
• In the pattern: Node2 a t
In an equation for ‘degree’:
degree (Node2 a t) = max (length t) (maximum (map degree t))
• Relevant bindings include
degree :: Tree a -> Int (bound at Esercizi_Haskell.hs:67:1)
|
| degree (Node2 a t) = max (length t) (maximum (map degree t))
解决方案
degree
用 type定义函数似乎没有多大意义degree :: [Tree a] -> Int
。如果我查询树列表的度数,我希望得到一个数字列表。特别是因为该列表可以包含许多不同的树,这些树不是较大树的子树。
degree :: Tree a -> Int
定义一个函数来计算特定树的度数更有意义。因此,我们可以将其实现为:
degree :: Tree a -> Int
degree Void2 = 0
degree (Node2 _ t) = max (length t) (maximum (map degree t))
然而,它在这里包含一个问题:如果Node2
没有孩子,则,map degree t
将返回一个空列表,并且maximum :: Ord a => [a] -> a
在一个空列表上会引发错误。但是,我们可以将其length t
作为元素之一传递,例如:
degree :: Tree a -> Int
degree Void2 = 0
degree (Node2 _ t) = maximum (length t : map degree t)
因此,我们在这里消除了代码中的列表输入以及第二个子句,因为空列表没有树 itef 的对应项。以上确实是一种计算树度数的方法。
我们可以在这里使用下划线 ( _
) 作为数据构造函数的第一个参数Node2
,因为我们对节点本身的值不感兴趣。
我们还可以将更多逻辑放在另一个函数children :: Tree a -> [Tree a]
中,例如:
children :: Tree a -> [Tree a]
children Void2 = []
children (Node2 _ t) = t
在这种情况下,我们可以degree
简单地定义为:
import Control.Applicative(liftA2)
degree :: Tree a -> Int
degree = maximum . liftA2 (:) length (map degree) . children
推荐阅读
- javascript - 聚焦自定义输入时未触发角度单击事件
- c# - 每个图表象限的不同背景颜色
- python - 发生异常:ModuleNotFoundError No module named *
- python - 从 shortest_distance 函数返回的距离图缺少某些顶点的条目
- python - Buildozer 在尝试安装 cython 时在项目安装阶段构建失败
- swift - 在swift中使switch case不区分大小写
- laravel - PDF 页眉和页脚 laravel snappy
- json - 快速解析 json 响应的问题
- javascript - 如何使用 dateDropper 插件格式化日期
- python - 我有 2 个组合框(comboBox_1,comboBox_2)comboBox_1 并用正确的数据填充组合框_2