为什么数字类型必须在printf(与putStr一起使用)中为脚本声明,而不是在ghci中声明?
问题描述:
为什么在作为脚本运行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)
答
GHCi只是简单地放宽了默认启用的默认规则(所以文字5
默认为Integer
),只是为了让您的生活更轻松。
通过启用ExtendedDefaultRules
,您可以在GHC中实现类似的效果。
请参阅GCHi docs以获得更详细的讨论。
你知道putStr是不需要的吗? – augustss
谢谢@augustss。我没有意识到这一点。我刚试过你的小费。当然,删除'putStr'不会消除_literal 3含糊错误。但是现在正确的表达式简化为'main = printf“abc%d \ n”(3 :: Int)'。 ... Haskell的数学简洁性是其最美丽的特征之一,因为它有助于阐明算法的本质,尤其是在强烈使用Hindley-Milner的情况下,尽管在这种情况下数字不能被消除。 –