2013-03-08 165 views
1

所以我想在Haskell中寫一個名爲Largest的函數,它找到列表中最大的元素,但是使用高階函數來實現。Haskell函數 - 最大

我是新來的Haskell所以這是我嘗試它不工作

largest :: [Int] -> Int 
largest [] = 0 
largest (head : tail) = if (head > tail) then head 
else (largest tail) 

我不知道是什麼高階函數的意思。

一些幫助將不勝感激。

回答

2

高階函數將一個或多個函數作爲其參數之一,或返回一個函數。在這種情況下,我假設高階參數應該是一個比較函數。這給出了一個簡單的定義爲最大:

largest :: [a] -> (a -> a -> Ordering) -> a 
largest (x:xs) cmp = go x xs 
    where go largest []  = largest 
      go largest (x:xs) = case cmp largest x of 
      LT -> go x xs 
      _ -> go largest xs 

還,只是爲了讓你知道,有一個功能叫做maximum前奏爲你做這個。 maximum [2,3,4,1] == 4

4

要解決您的嘗試:

largest :: [Int] -> Int 
largest [] = 0 
largest (head : tail) = max head (largest tail) 

注意,這隻會工作的非負數(您可以通過判定空列表沒有最大解決這個問題 - 或通過使用類似前奏曲的maximumminBoundInt而不是0,但這不起作用,例如Integer)。

但是,這仍然不使用更高階的函數。這種問題適合的功能是foldl(或更好的Data.List.foldl')或foldr,但我不想破壞樂趣。

1

要完成現有的答案,

你必須克服的第一個問題是嘗試編譯代碼,或至少理解的錯誤消息。這個提示應該給你提供關於你面臨的問題的很好的指導,以及如何修改它以獲得一個正確的版本(即使你沒有填寫高級功能的要求,至少你會有一個工作的)。

對於這一點,讓我們來看看模式條款的類型簽名,(頭:尾)

首先對(:)功能,我們有,

(:) :: a -> [a] -> [a] 

然後我們推導出以下類型,(這是爭論的(:)),

  • 頭是Int類型的。
  • 尾部類型爲[Int]。

再次,讓我們一起來看看類型簽名(>)

(>) :: Ord a => a -> a -> Bool 

如果我們忽略了約束類,以保持它的簡單,我們有,

(>) :: a -> a -> Bool 

還是在您的代碼是

.... 
if (head > tail) ... 
.... 

哪個可以重寫,再次簡化爲

.... 
if ((>) head tail)) ... 
.... 

使用以前所有的言論,你應該能夠重建提供給(>)函數的類型和理解這個問題。

然後,您可以更正您的代碼,並使使其工作
之後你可以看看high order function,然後使它正確

作爲一般性評論,當你被困在一個複雜的問題上時,試着把它分解成更小的問題,並且對於每個子問題嘗試應用以下烹飪原理。

讓它工作,
作出正確的,
make如果快。

0
if (head > tail) 

首先,你不需要括號。其次,更嚴重的是,head是一個整數,但是tail整數列表。你無法比較這兩件事。

largest (head : tail) = if (head > tail) then head 
else largest tail 

這不是正確的縮進。 else必須至少縮進至if。您可以把then和在同一行的else,或做類似

if head > tail 
    then head 
    else largest tail 

(同樣,你實際上並不需要括號 - 雖然他們沒有傷害任何東西。)

最後一點,有一個名爲head的預定義函數,以及一個名爲tail的函數,所以這些函數不是變量名稱的最佳選擇。慣用的Haskell選擇是xxs(「x」的複數)。你會看到很多這樣寫的代碼。它也有助於提醒你,x是一件事情,xs是一個事情的列表。

+0

http://ideone.com/3veT8I顯示'else'在'if'的左邊縮進,但它工作正常。 – 2013-03-16 14:09:43