2017-07-04 38 views
3

我是函數式編程和Haskell的新手。試圖學習它。不知道什麼是錯的,定義如下:Haskell函數定義不按預期方式工作

功能定義test.h

drop5 [a] = drop 5 [a] 

嘗試當我改變了定義以下使用此功能,我得到程序錯誤

$:load test.h 
$drop5 [2,3,4,5,6,7,8] 
Program error: pattern match failure: drop5 [2,3,4,5,6,7,8] 
$:t drop5 
drop5 :: [a] -> [a] 

有用;這意味着它接受一個列表並丟棄列表

drop5 ns = drop 5 ns 

在這種情況下,當打印類型我看到的第5個元素:

$:t drop5 
drop5 :: [a] -> [a] 

我不知道爲什麼比第二不同的第一個定義?那麼錯誤「程序錯誤:模式匹配失敗的意思」是什麼?

回答

5

在第一個定義中,[a]是一種模式,它只與一個元素的列表匹配,並且該元素在規則的右邊部分中被稱爲a

因此,您將函數定義爲只接受單例列表。

此外,從一個列表中刪除5個元素,只有一個顯然會導致一個空列表(就像刪除任何正數元素一樣)。

+0

這很有道理。謝謝!!我嘗試drop5 [2],並沒有返回任何錯誤。 – patronus

4

你的函數定義:

drop5 [a] = drop 5 [a] 

指定條款只有「火」的名單與恰好一個元素。事實上在一個函數定義[a]不是參數類型,它是模式。模式[a]意味着我們正在處理一個只有一個元素的列表。

如果用-Wall編譯您將獲得:

<interactive>:1:1: warning: [-Wincomplete-patterns] 
    Pattern match(es) are non-exhaustive 
    In an equation for ‘drop5’: 
     Patterns not matched: 
      [] 
      (_:_:_) 

編譯器/解釋器從而產生一個警告,兩個圖案不包括:一個用於列表,以及一個用於列表兩個或多個元素

+0

有趣。編譯器如何知道它是模式還是參數?此外,我使用hugs98開始(這是建議在功能編程課程edx入門)。我不知道如何在這裏編譯文件。 – patronus

+1

@patronus:參數*是*模式。然而,你可以 - 在頭上 - 使用一種模式。在這種情況下,如果模式匹配,則該行被「解僱」。模式匹配是幾乎所有函數式編程語言共享的一個方面。 –

2

[a]告訴哈斯克爾說只有一個列表中的元素,而ns告訴Haskell中,它可以是任何東西(甚至一個布爾值,如果你想),直到你完成的功能和它所標識的輸出和輸入型。你也可以明確地告訴Haskell的輸入和輸出類型是通過添加這上面的內容是什麼:

drop5 :: [Integer] -> [Integer] 

這可以通過在GHCI做:t drop5被發現。

此外,在附註中,可以減少此代碼。通過將其更改爲:

drop5 = drop 5 

這可能沒有什麼意義,你的權利,但你瞭解你應該學會所有的Haskell函數一個參數。

相關問題