变量不在范围内:a

Variable not in scope: a

我正在尝试制作一个简单的归并排序函数。几乎完成了代码,但是:

m_sort :: (Ord a) => [a] -> [a]
m_sort d
     | d == [] = []
     | d == [a] = [a]
     | otherwise = merge (m_sort (fst $ split d)) (m_sort (snd $ split d))

出于某种原因,我得到了 Haskell_training.hs:137:21: error: Variable not in scope: a。排除 | d == [a] = [a] 会导致很好的编译,但没有它就无法工作。我没有看到模式匹配存在一些非常明显的问题吗?

Is there some really obvious problem with pattern matching I'm not seeing?

是的,当然:您还没有编写模式匹配! (好吧,你写了一个简单的 d,它匹配任何东西并将它命名为 d。)你写的是一个守卫,它必须是类型 Bool 的表达式。虽然 d == [a] 在语法上没问题,并且如果 da 具有适当的类型,则可能具有 Bool 类型,但它在这里不起作用,因为您没有任何 ad

进行比较

你可能想要这个:

m_sort [] = []
m_sort [a] = [a]
m_sort d = merge ...

现在,不再是表达式中包含术语 [a] 的表达式引用某个名为 a 的变量,而是模式匹配,它会查找形状为 a 的术语单元素列表并将 a 绑定到该元素。

Iirc,这不是模式匹配 - 你问的是 d 是否等于 [a],因为你没有定义 a 是什么导致了问题。

请记住,您需要一个评估为 Bool 的表达式作为守卫中的条件,因此 length(d) == 1 之类的东西应该有效:

m_sort :: (Ord a) => [a] -> [a]
m_sort d
     | d == []        = []
     | length d  == 1 = d
     | otherwise      = merge (m_sort (fst $ split d)) (m_sort (snd $ split d))

或者,您可以将您的函数声明为多个部分(无论如何我认为这是更好的做法),如@DanielWagner 的回答,这将让您像您尝试的那样使用模式匹配。