我正在用haskell在语法上挣扎。这很简单,但是我被困了。
我正在尝试编写一个获取列表并找到最小值的Findmin函数。这是我的代码,我尝试了很多句法的事情,以至于我可以得到任何帮助。
findMin [] = [0]
findMin list = if any < head list then findMin(tail) else take 1
我得到了各种类型错误。怎么了?
(如果它完全有帮助,我在面向对象的编程中具有背景)
我看到您已经在评论中弄清楚了,但是我希望在这里添加一些东西以提供帮助。我还觉得我应该迅速提及Haskell已经具有minimum
功能,以防万一有人偶然发现这个人不仅要学习语言,而且实际上需要某种功能。
首先让我们谈谈类型。我通常希望findMin
功能样式返回最小值,而不是列表中的该值,以便类型为: findMin :: (Num a, Ord a) => [a] -> a
=>
之前的事物添加上下文到功能类型。这限制了a
可以是有序的所有内容(否则我们如何找到最低限度)。其次,Num a
强制a
是一个数字,这是必要的,因为您指定空列表的情况应为0。
我将解释其他两种编写Findmin功能的方法,试图使它们比您的定义更简洁(Haskell的好处之一就是它可以是多么简洁,我在学习看到多个倍数时也会有所帮助可能性)。第一个将使用递归和守卫,第二个将使用列表理解。
我们对findMin [] = 0
做不到太多
我们需要谨慎使用递归定义,因为最终我们将评估findMin []
并始终获得0,因此我们需要通过定义单个值的案例之前停止递归: findMin [x] = x
将列表作为参数传递给函数时,您可以将其元素分开并给它们每个名称,因此(x:xs)
表示值x
是第一个元素,后面是元素 xs
的列表。
对于此定义,我们将独自定义前两个元素,然后是其余元素:
findMin (x:y:xs)
| x < y = findMin (x:xs)
| otherwise = findMin (y:xs)
守卫使我们可以根据条件具有多个功能定义。如果x < y
我们要摆脱Y,因为它不能是最小值,因此我们找到x
的最小值和其余元素xs
。如果x
不小于y
,则最小值为y
或xs
中的一个值之一。
定义此功能的第二种方法是使用列表理解(这是我的最爱,因为它特别简洁)。
我们不使用递归,因此我们不需要一个元素的情况,我们可以保留一个空列表的定义,然后直接进入带有元素的任何列表:
findMin xs = head [x | x <- xs, all (>= x) xs]
那是怎么回事?[x | x <- xs]
创建x
值的列表,其中x
是xs
中的所有元素。然后,我们添加一个条件,说我们只需要当all (>= x) xs
含义xs
的所有元素大于或等于xs
。
这将导致最小元素的列表。如果最小发生一次,则可能具有一个元素,或者如果多次发生,则可能具有多个元素。无论哪种方式,它们都是相同的,所以我们只使用head
。
希望这有所帮助,并希望您有有趣的学习Haskell。随时询问您是否有任何疑问:)
在GHCI中,此功能似乎可以解决您的技巧:
let findMin x = if length x > 1 then min (head x) (findMin (tail x)) else head x
我在尝试在这里回答一些问题时正在学习,因此任何反馈都将不胜感激。