haskell - Haskell:错误无法匹配预期类型
问题描述
有人可以帮助我弄清楚我在这段代码中做错了什么。我尝试编写一个添加两个多项式函数的代码,但我总是收到以下错误消息:
main.hs:6:45: error:
* Couldn't match expected type `[a]' with actual type `Poly a'
* In the second argument of `(:)', namely `polyadd (P xs) (P ys)'
In the first argument of `P', namely
`((x + y) : polyadd (P xs) (P ys))'
In the expression: P ((x + y) : polyadd (P xs) (P ys))
* Relevant bindings include
ys :: [a] (bound at main.hs:6:26)
y :: a (bound at main.hs:6:24)
xs :: [a] (bound at main.hs:6:15)
x :: a (bound at main.hs:6:13)
polyadd :: Poly a -> Poly a -> Poly a (bound at main.hs:4:1)
|
6 | polyadd (P (x:xs)) (P (y:ys)) = P ((x+y) : polyadd (P xs) (P ys))
| ^^^^^^^^^^^^^^^^^^^^^
这是我的代码
data Poly a = P [a] deriving (Show, Eq)
polyadd :: (Num a, Eq a) => Poly a -> Poly a -> Poly a
polyadd (P ([])) (P (ys)) = P ys
polyadd (P (xs)) (P []) = P xs
polyadd (P (x:xs)) (P (y:ys)) = P ((x+y) : polyadd (P xs) (P ys))
解决方案
在这个表达式中:
(x+y) : polyadd (P xs) (P ys)
您正在尝试通过将 head 附加到 tail来创建列表。这就是运营商的意思。这就是它的作用。从头部和尾部创建一个列表。(x+y)
polyadd (P xs) (P ys)
(:)
问题是,列表的尾部应该是列表,但polyadd (P xs) (P ys)
不是列表,而是Poly a
类型签名中定义的 a 。所以它不适合 operator (:)
,它期望它的右操作数是一个列表。所以编译器会准确地告诉你:无法将预期类型 '[a]' 与实际类型 'Poly a' 匹配
根据我的读心能力告诉我你的意图,你真正想做的是预先(x+y)
添加到包含在Poly a
. 为此,您必须解构第Poly a
一个:
polyadd (P (x:xs)) (P (y:ys)) =
let (P zs) = polyadd (P xs) (P ys)
in P ((x+y) : zs)
Poly a
但是当然,不要在每一步打开和重新包装值,而是先构造结果列表,然后再包装它,这样会更干净、更有效。为此,您需要一个单独的函数来执行列表遍历,然后调用该函数,并将其结果包装在Poly
:
polyadd :: (Num a, Eq a) => Poly a -> Poly a -> Poly a
ployadd (P as) (P bs) = P (inner as bs)
where
inner [] ys = ys
inner xs [] = xs
inner (x:xs) (y:ys) = (x+y) : inner xs ys
推荐阅读
- java - 如何使用高斯分布在道路网络地图中创建距离,最好在 Java 中模拟现实世界场景?
- angular - 茉莉花测试用例中的发射测试
- html - Bootstrap 4 响应时显示导航链接
- java - 求Java标准库中异步方法的例子
- sql - 使用当前日期和自定义时间更新查询在 Postgresql 中不起作用
- php - Laravel:如何在使用模板文件导出时更改 startcell
- typescript - 在 Vuejs 项目中找不到导出的组件
- args - Discord Node JS TypeError:args.slice 不是函数
- firebase - 为什么我的 Flutter 应用写入实时数据库而不是 Cloud Firestore?
- spring-boot - Spring Integration Sftp:有时需要超过 15 分钟才能完成操作