【问题标题】:Couldn't match expected type with actual type无法将预期类型与实际类型匹配
【发布时间】:2015-04-15 17:34:24
【问题描述】:

我最近开始学习 Haskell,无法弄清楚我的代码有什么问题,但最终失败了。

这是我的代码的一部分,显示我已经为 Graph 类型声明了数据构造函数,它是一个值的元组列表和该值的列表。

data Graph a = Graph [(a,[a])] deriving (Ord, Eq, Show)

这是两个整数元组的类型同义词,

type Point = (Int, Int)

最后这段代码是使用第一个参数(即搜索/散列值)找到图形的第二个参数

pointNeighbor :: Graph Point -> Point -> [Point]
pointNeighbor (x:xs) point = if fst x == point then snd x else pointNeighbor (xs) point

这是我尝试加载模块时收到的错误消息

hw1.hs:37:16: 无法匹配预期类型“图形点” 实际类型为‘[(Point, [Point])]’ 在模式中: x : xs 在“pointNeighbor”的方程中: pointNeighbor (x : xs) 点 = if fst x == point then snd x else pointNeighbor (xs) point

hw1.hs:37:79: 无法匹配预期类型“图形点” 实际类型为‘[(Point, [Point])]’ 在‘pointNeighbor’的第一个参数中,即‘(xs)’ 表达式中:pointNeighbor (xs) 点

似乎 Graph Point 应该被识别为 [(Point,[Point])] 但显然它给了我这个错误,我在网上找不到任何解决方案。

提前致谢:)

【问题讨论】:

    标签: haskell


    【解决方案1】:

    您的函数要求第一个参数是Graph 类型。由于定义了Graph,因此只有一种方法可以做到这一点:使用Graph 值构造函数('Graph' 一词出现在=右侧 data 定义)。

    但是,您尝试执行的模式匹配假装第一个参数是普通的 List,而不是 List,它已成为 Graph 值构造函数的一部分。

    模式匹配应该是(Graph (x:xs)),并且else子句中的递归调用应该使用(Graph xs),如下所示:

    pointNeighbor :: Graph Point -> Point -> [Point]
    pointNeighbor (Graph (x:xs)) point = 
        if fst x == point 
            then snd x 
            else pointNeighbor (Graph xs) point
    

    另请注意,当列表为空时,您没有定义基本情况。

    【讨论】:

    • 谢谢,我现在明白了:) 我还注意到我也应该将 (xs) 部分修复为 (Graph (xs))。
    【解决方案2】:

    因为Graph 是一个数据构造函数,你必须对它进行模式匹配:

    pointNeighbor :: Graph Point -> Point -> [Point]
    pointNeighbor (Graph (x:xs)) point = if fst x == point then snd x else pointNeighbor (Graph xs) point
                   ^^^^^                                                                  ^^^^^
    

    【讨论】:

    • 我刚刚意识到,我的解决方案和你的一样,需要在 else 子句中对 pointNeighbor 的递归调用周围再次使用 Graph ... (Graph xs) 或递归调用将遭受与原版 OP 相同的命运。
    • 谢谢,我现在明白了:)
    猜你喜欢
    • 2016-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-29
    • 2019-04-23
    • 2020-02-29
    • 2018-04-05
    相关资源
    最近更新 更多