1
所以我剛剛遇到了ghci如下:哈斯克爾ghci中讀取*行爲和最大
(*) (read "10") (read "20")
收益200如預期。不過,此行
(max) (read "10") (read "20")
拋出異常:
*** Exception: Prelude.read: no parse
而且我真的不能找出這樣的ghci的行爲的原因。任何幫助,將不勝感激!
所以我剛剛遇到了ghci如下:哈斯克爾ghci中讀取*行爲和最大
(*) (read "10") (read "20")
收益200如預期。不過,此行
(max) (read "10") (read "20")
拋出異常:
*** Exception: Prelude.read: no parse
而且我真的不能找出這樣的ghci的行爲的原因。任何幫助,將不勝感激!
這是GHCi違約規則的一個實例。當遇到不明確的類型時,它會選擇()
(「unit」)作爲默認值。所以它試圖讀取10
作爲()
類型的值,該值無法解析。
的類型不明確,因爲read
的返回類型超載對Read
任何情況下工作,並max
的參數類型超載對Ord
任何情況下工作,所以編譯器沒有任何辦法知道哪種你打算爲中間值:
read :: (Read a) => String -> a
max :: (Ord a) => a -> a -> a
您還將看到此行爲如果你只是寫:
read "10"
但是寫這將工作:
read "()"
一種解決方案是給一個明確的類型註釋:
max (read "10" :: Int) (read "20" :: Int)
這將返回20
預期。
你也可以用命令行標誌,禁用此行爲:
ghci -XNoExtendedDefaultRules
或者用GHCI命令:
:set -XNoExtendedDefaultRules
,然後你會得到的線沿線的一個相應的錯誤信息「沒有Ord a0
...的實例...類型變量a0
不明確」。
事實上,一個':: Int'就足夠了。 – Adrian
@ addy2012:的確如此,但在這種情況下,我更願意明確並避免依賴推理。例如,我通常更喜歡寫'[a,b,c] :: [Int]'而不是'[a :: Int,b,c]',儘管它有點多餘。 –