我试图制作一个简单的合并排序功能。几乎完成了代码,但是:
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]
导致编译很好,但没有它就不会工作。模式匹配是否有一些非常明显的问题我没有看到?
答案 0 :(得分:8)
模式匹配是否有一些非常明显的问题我没有看到?
是的,确定:你还没有写过模式匹配! (好吧,你写了一个简单的,d
,它匹配任何东西,并命名为d
。)你所写的是一个守卫,它必须是Bool
类型的表达式。虽然d == [a]
在语法上是可以的,并且如果Bool
和d
具有适当的类型,则可能有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的答案中一样,它可以让你像你一样尝试使用模式匹配。