2017-10-17 72 views
1

爲什麼在作爲腳本運行putStr (printf "abc%d\n" 3)3含糊不清,但在運行ghci時不是含糊不清?也就是說,爲什麼我必須在腳本中聲明3的類型,而不是ghci?爲什麼數字類型必須在printf(與putStr一起使用)中爲腳本聲明,而不是在ghci中聲明?

這裏是內ghci操作:

$ ghci 
GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help 
Loading package ghc-prim ... linking ... done. 
Loading package integer-gmp ... linking ... done. 
Loading package base ... linking ... done. 
Prelude> putStr "abc3\n" 
abc3 
Prelude> import Text.Printf 
Prelude Text.Printf> printf "abc%d\n" 3 
abc3 
Prelude Text.Printf> let main = putStr (printf "abc%d\n" 3) 
Prelude Text.Printf> main 
abc3 
Prelude Text.Printf> let main = printf "abc%d\n" 3 :: String 
Prelude Text.Printf> main 
"abc3\n" 
Prelude Text.Printf> :quit 
Leaving GHCi. 

這裏是script的正確的操作,Int聲明時:

$ cat runmain-good 
#!/usr/bin/env runghc 
import Text.Printf 
main = putStr (printf "abc%d\n" (3 :: Int)) 
$ ./runmain-good 
abc3 

下面是當3類型是script的錯誤操作曖昧......與典型的用戶友好的Haskell錯誤:

$ cat runmain-bad 
#!/usr/bin/env runghc 
import Text.Printf 
main = putStr (printf "abc%d\n" 3) 
$ ./runmain-bad 

runmain-bad:3:16: 
    No instance for (PrintfArg a0) arising from a use of `printf' 
    The type variable `a0' is ambiguous 
    Possible fix: add a type signature that fixes these type variable(s) 
    Note: there are several potential instances: 
     instance [safe] PrintfArg Char -- Defined in `Text.Printf' 
     instance [safe] PrintfArg Double -- Defined in `Text.Printf' 
     instance [safe] PrintfArg Float -- Defined in `Text.Printf' 
     ...plus 12 others 
    In the first argument of `putStr', namely `(printf "abc%d" 3)' 
    In the expression: putStr (printf "abc%d" 3) 
    In an equation for `main': main = putStr (printf "abc%d" 3) 

runmain-bad:3:33: 
    No instance for (Num a0) arising from the literal `3' 
    The type variable `a0' is ambiguous 
    Possible fix: add a type signature that fixes these type variable(s) 
    Note: there are several potential instances: 
     instance Num Double -- Defined in `GHC.Float' 
     instance Num Float -- Defined in `GHC.Float' 
     instance Integral a => Num (GHC.Real.Ratio a) 
     -- Defined in `GHC.Real' 
     ...plus 11 others 
    In the second argument of `printf', namely `3' 
    In the first argument of `putStr', namely `(printf "abc%d" 3)' 
    In the expression: putStr (printf "abc%d" 3) 
+0

你知道putStr是不需要的嗎? – augustss

+0

謝謝@augustss。我沒有意識到這一點。我剛試過你的小費。當然,刪除'putStr'不會消除_literal 3含糊錯誤。但是現在正確的表達式簡化爲'main = printf「abc%d \ n」(3 :: Int)'。 ... Haskell的數學簡潔性是其最美麗的特徵之一,因爲它有助於闡明算法的本質,尤其是在強烈使用Hindley-Milner的情況下,儘管在這種情況下數字不能被消除。 –

回答

4

GHCi只是簡單地放寬了默認啓用的默認規則(所以文字5默認爲Integer),只是爲了讓您的生活更輕鬆。

通過啓用ExtendedDefaultRules,您可以在GHC中實現類似的效果。

請參閱GCHi docs以獲得更詳細的討論。

相關問題