2016-09-18 60 views
1

超級基本問題 - 但我似乎無法得到明確的答案。下面的函數將無法編譯:基本的Haskell函數類型?

randomfunc :: a -> a -> b 
randomfunc e1 e2 
    | e1 > 2 && e2 > 2  = "Both greater" 
    | otherwise    = "Not both greater" 

main = do 
    let x = randomfunc 2 1 
    putStrLn $ show x 

我很困惑,爲什麼這不起作用。這兩個參數都是類型'a'(Ints),返回參數是類型'b'(字符串)?

錯誤:

"Couldn't match expected type ‘b’ with actual type ‘[Char]’" 

回答

7

不完全。您的函數簽名指示:對於所有類型ab,如果給出a類型的兩件事,randomfunc將返回b類型的東西。

但是,randomFunc返回String[Char])。而且,由於你比較e12對方,你不能使用所有a的,只有那些能與>使用:

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

注意e1 > 2也需要一種方式來創建這樣一個從a2

(> 2) :: (Num a, Ord a) => a -> Bool 

因此,無論使用特定類型的,或者確保你正確地處理所有這些約束條件:

randomfunc :: Int -> Int -> String 

randomFunc :: (Ord a, Num a) => a -> a -> String 
2

Both parameters are type 'a' (Ints) and the return parameter is type 'b' (String)?

在Haskell的類型簽名,當你編寫與作爲a小寫字母開頭這樣的名字,編譯器隱式添加forall a.到類型的開頭。所以,這就是編譯器實際看到:

randomfunc :: forall a b. a -> a -> b 

類型簽名聲稱你的函數會因任何(「所有」)類型ab呼叫者拋出在你的工作。但是這不適用於你的功能,因爲它只能分別在IntString上運行。

你需要讓你的類型更加具體:

randomfunc :: Int -> Int -> String 

在另一方面,也許你打算要求編譯器自動填寫您ab,而不是聲稱,它會工作全部爲ab。在這種情況下,您真正​​需要的是PartialTypeSignatures功能:

{-# LANGUAGE PartialTypeSignatures #-} 

randomfunc :: _a -> _a -> _b