merge ::(ord a) => [a] ->[a] -> [a]
merge [][] = []
merge [a][b] = [[a,b]|a<-mergesort [a],b<- mergesort [b]]
mergesort ::(a -> Bool) -> [a] -> [a]
mergesort [] = []
mergesort (x:xs) = if xs >=2 then mergesort xs else mergesort(x:xs)
| comparision > 0 = x:xs
| comparision <= 0 = xs:x
where comparision = x-xs
这就是我为merge and mergesort编写的代码,当然不是正确的。
你能提出一些修改代码的建议吗?请不要给我答案....
就目前而言,编译器给出的唯一错误是:
test.hs:8:34: error: parse error on input ‘|’
|
8 | | comparision > 0 = x:xs
| ^
因此,我将假设这是你所坚持的,并谈论如何解决这个问题。
基本问题是警卫(即,具有管道字符|
后跟条件的句法形式)仅允许在绑定站点(如函数方程或case
语句内)。你把你的包括在一个错误的位置。目前还不完全清楚那些警卫的意思,所以我不太确定如何帮助你把他们放在正确的位置。
也许我能给出的最好的帮助是用一些抽象的例子来描述它们的意思,并让你弄清楚你希望它们去哪里。以此为例:
f x y | cond1 = val1
| cond2 = val2
| cond3 = val3
这定义了一个名为f
的新函数,它接受两个参数。它命名参数x
和y
。然后,为了确定返回什么值,它会检查警卫,寻找第一个评估为True
的值。因此,如果cond1
评估为True
,则函数返回val1
;如果cond1
评估为False
但cond2
评估为True
,则函数返回val2
;如果cond1
和cond2
评估为False
但cond3
评估为True
,则函数返回val3
。 (..如果所有三个条件都评估为False
,它会抛出一个运行时异常。)
现在让我们看看你使用的语法:
mergesort (x:xs) = if xs >=2 then mergesort xs else mergesort(x:xs)
| comparision > 0 = x:xs
| comparision <= 0 = xs:x
在这里,您要定义一个名为mergesort
的新函数,它接受一个参数。它将该参数与模式x:xs
相匹配。然后它似乎返回if xs >=2 then mergesort xs else mergesort(x:xs)
的结果。但这两个额外的守卫在做什么呢?我不知道。也许你想象如果comparision > 0
,那么函数将返回x:xs
而不是if xs >=2 then ... else ...
。如果是这样,你应该这样写:
mergesort (x:xs) | comparision > 0 = x:xs
| comparision <= 0 = xs:x
| otherwise = if x >=2 then mergesort xs else mergesort(x:xs)
或许你想象如果comparision > 0
,那么递归调用将使用x:xs
而不是(x:xs)
。如果是这样,你应该这样写:
mergesort (x:xs) | comparision > 0 = if x >=2 then mergesort xs else mergesort(x:xs)
| comparision <= 0 = if x >=2 then mergesort xs else mergesort(xs:x)
我不确定是什么意思。
无论如何,希望这可以帮助您解决您的解析错误,并让您到达可以查看下一个编译器错误的点,并自己修复这些错误。
有几个问题要问自己:
merge
和mergesort
这些函数做什么?假设我有一个我想要排序的列表 - 只有一个列表,还没有拆分。我应该调用哪个函数来使用合并排序的实现?mergesort :: (a -> Bool) -> [a] -> [a]
,mergesort
应该有多少参数?x
和xs
?是否所有函数都应用于为这些类型定义的变量?我看到函数-
,(:)
,(>=)
和mergesort
。由ghci的mergesort
为这些函数(:t
除外)提供的类型如下:
(-) :: Num a => a -> a -> a
。这意味着:
(-)
有两个相同类型的参数。这种类型必须属于类型类Num
- 也就是说,它必须是某种数字。
(-)
返回该类型的单个值。
(:) :: a -> [a] -> [a]
。这意味着:
(:)
采用一种类型的参数,另一种参数是该类型的值列表。
(:)
返回该类型的值列表。
(>=) :: Ord a => a -> a -> Bool
。这意味着:
(>=)
有两个相同类型的参数。此类型必须属于Ord
类型类 - 也就是说,必须可以比较该类型的两个值,并说一个值大于,小于或等于另一个值。 (在Prelude
中,这包括类型类Num
的所有成员。)
(>=)
返回Bool
。您还应该考虑如何构建实现。考虑合并排序的工作原理。查看步骤,考虑如何将这些步骤实现为函数,以及如何使用一个mergesort
函数将这些步骤连接在一起。一旦计划好设计,那么您应该担心语法。