2011-06-12 48 views
1

我有以下功能:`奧德A =>`或`民一=>'

which (x:xs) = worker x xs 
worker x [] = x 
worker x (y:ys) 
    | x > y  = worker y ys 
    | otherwise = worker x ys 

,我想知道我應該如何定義這些上述功能whichworker類型的簽名?

例如,下列哪種方法是最好的類型簽名的工人?

worker :: Num a => a -> [a] -> a

worker :: Ord a => a -> [a] -> a

我只是很困惑,並沒有得到這三個我應該選擇。我會很感激你的想法。謝謝。

+1

你的功能是什麼*用於*?這是數字嗎?整型?任何可以訂購的東西? – Gabe 2011-06-12 13:37:54

+0

@Gabe輸出是一個數字(即'Float'或'Int'),因此上面的'>'符號。現在我只是不確定它應該是'Ord a => ...'還是'Num a => ...' 只是真的很困惑!感謝您的詢問,幫助我消除了列表中的第三個:-) – maclunian 2011-06-12 13:41:42

+0

@maclunian:您可以在有訂單的任何東西上使用'>',而不僅僅是數字。這就是爲什麼使用'Ord'而不是'Num'的原因。 – sepp2k 2011-06-12 13:45:43

回答

6

如果你定義了沒有顯式類型簽名的函數,Haskell會推斷出最通用的函數。如果你不確定,這是找出你的定義將被讀取的最簡單的方法;您可以將其複製到您的源代碼中。一個常見的錯誤是錯誤地鍵入一個函數,然後在其他地方得到一個令人困惑的類型錯誤。

無論如何,通過在ghci中輸入:i Num或通過閱讀文檔,您可以獲得有關Num課程的信息。該Num類爲您提供了+*-negateabssignumfromInteger,還有的EqShow每一個功能。請注意,<>不在那裏!要求Num的值並試圖比較它們實際上會產生類型錯誤 - 並不是每種數字都可以進行比較。

所以它應該是Ord a => ...,因爲如果你嘗試過Num a => ...會產生一個錯誤類型。

+0

但是想一想,你不能只用'worker :: a - > [a] - > a'嗎? – maclunian 2011-06-12 13:52:41

+0

你不能。既然你有表達式'x> y',它會抱怨'沒有(Ord a)'的實例。 – 2011-06-12 13:54:49

0

編輯:意見後改變了我的答案。

這取決於你希望能夠比較什麼。如果你想能夠比較DoubleFloatIntIntegerChar然後使用Ord。如果您只想比較Int,那麼只需使用Int即可。

如果你有這樣一個問題,只是看的類型類的實例告訴你希望能夠在功能上要使用的類型。

+0

雖然想着,難道你不能只用'worker :: a - > [a] - > a'嗎? – maclunian 2011-06-12 13:53:13

+0

是的,你可以。但是,儘可能多地使用類型聲明的力量,因爲編譯器會捕獲與類型相關的錯誤。下面是一個很好的解釋:http://book.realworldhaskell.org/read/writing-a-library-working-with-json-data.html#id598932 – rzetterberg 2011-06-12 13:58:14

+0

不,只是'Num'不行。 – augustss 2011-06-12 15:25:13

0

我總是會與奧德類型約束去。它是最通用的,因此可以更頻繁地重用。

使用Num over Ord沒有任何優勢。

詮釋可能有小的優勢,因爲它是不多態性,將不需要字典查找。如果我需要性能,我會使用Ord並使用專用雜注。

+0

但是想一想,難道你不能只用'worker :: a - > [a] - > a'嗎? – maclunian 2011-06-12 13:52:47

+0

不,(>)是Ord類型類的一部分。沒有約束它沒有定義 – llayland 2011-06-12 14:23:18

3

如果你考慮你的函數做什麼,你會看到which xs返回xs的最小值。什麼可以有最小值? Ord erable的列表!

2

問問ghci,看看它說什麼。我只是將你的代碼複製到一個文件中並將其加載到ghci中。然後我用:t這是一個特殊的ghci命令來確定某種東西的類型。

ghci> :t which 
which :: (Ord t) => [t] -> t 
ghci> :t worker 
worker :: (Ord a) => a -> [a] -> a 

Haskell的類型推斷是在大多數情況下,很聰明;學會信任它。其他答案充分說明了爲什麼在這種情況下應該使用Ord;我只是想確保ghci被明確提及爲確定某種東西的技巧。

相關問題