【发布时间】:2019-09-23 23:11:30
【问题描述】:
当我尝试使用 GHCI 编译我的脚本时,我正在努力使用 Haskell 的语法,并且收到“错误:输入‘if’时解析错误”。我的代码的目的是返回无序列表的最小值和最大值。它通过将列表分成两半并找到每一半的最小值和最大值来递归地执行此操作。如果列表只有一个元素,它只会返回该元素既是最大值又是最小值,如果列表有两个元素,它会进行简单的比较以找到最小值和最大值。这是我的代码,“splitlist”函数取自在线资源:
splitlist :: [a] -> ([a], [a])
splitlist xs = splitAt ((length xs + 1) `div` 2) xs
minMax :: [Int] -> [Int]
minMax x
if length x == 1 then
[x, x]
else if length x == 2 then
if (head x > tail x) then
[tail x, head x]
else
[head x, tail x]
else
listOfLists = splitlist x
list1 = listOfLists!!0
list2 = listOfLists!!1
minMax1 = minMax list1
minMax2 = minMax list2
if (minMax1!!0 < minMax2!!0) then
min = minMax1!!0
else
min = minMax2!!0
if (minMax!!1 > minMax2!!1) then
max = minMax1!!1
else
max = minMax2!!1
[min, max]
我也怀疑我并没有尝试以 Haskell 的方式来做这件事,我是一个初学者,仍然不小心把它当作 python 对待。理想情况下,如果有人能告诉我我的方法做错了什么,然后向我展示一种更符合 Haskell 设计原则的方法,我将非常感激。
【问题讨论】:
-
恐怕不是一个快速的答案,但如果你是 Haskell 的新手,那么我强烈推荐 LYAH。除此之外,这将教你如何编写惯用的 Haskell 代码,使用高阶函数 - 然后你将看到如何在一行代码中找到列表的最小值和最大值,而不必做所有这些丑陋的事情if/else 语句。 (尽管这样做很天真,但还有比这种丑陋的分而治之更好的选择。不用说,有标准库函数可以找到列表的最小值和最大值。)
-
你又错过了
minMax x和函数体之间的=。 -
FWIW 将列表分成两半对此目的似乎不是很有用。无论如何,您能做的最好的事情就是对元素进行线性扫描,那么为什么不这样做呢?
-
Haskell 中没有赋值。名称可以定义为引用值,使用
let或where。 -
作为一个经验法则,您应该避免在代码中使用像
head,tail,!!这样的部分函数,并使用模式匹配来代替,这通常会导致代码更简单。length xs == 1也是一种反模式,当 O(1) 模式匹配就足够并免费提供头部和尾部时,成本为 O(N)。
标签: if-statement haskell syntax