变量不在范围内:a

时间:2017-12-14 18:30:21

标签: haskell scope pattern-matching mergesort

我试图制作一个简单的合并排序功能。几乎完成了代码,但是:

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]导致编译很好,但没有它就不会工作。模式匹配是否有一些非常明显的问题我没有看到?

2 个答案:

答案 0 :(得分:8)

  

模式匹配是否有一些非常明显的问题我没有看到?

是的,确定:你还没有写过模式匹配! (好吧,你写了一个简单的,d,它匹配任何东西,并命名为d。)你所写的是一个守卫,它必须是Bool类型的表达式。虽然d == [a]在语法上是可以的,并且如果Boold具有适当的类型,则可能有a类型,但它不会在这里工作,因为您不会t有a来比较d到。

你可能想要这个:

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

现在不是让一个表达式[a]的表达式引用一个名为a的变量,而是一个模式匹配,它寻找一个形状为一的术语 - 元素列表并将a绑定到该元素。

答案 1 :(得分:0)

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的答案中一样,它可以让你像你一样尝试使用模式匹配。