Haskell 为什么必须在printf(与putStr一起使用时)中为脚本声明数字类型,而不是为ghci声明数字类型?

Haskell 为什么必须在printf(与putStr一起使用时)中为脚本声明数字类型,而不是为ghci声明数字类型?,haskell,types,printf,ghci,Haskell,Types,Printf,Ghci,为什么PUTSR printf abc%d\n 3中的3在作为脚本运行时不明确,而在ghci中运行时则不明确?也就是说,为什么我必须在脚本中声明类型3而不是ghci 以下是ghci内部的操作: 以下是声明为Int时脚本的正确操作: 下面是当3的类型不明确时脚本的错误操作。。。对于典型的用户友好Haskell错误: $ cat runmain-bad #!/usr/bin/env runghc import Text.Printf main = putStr (printf "abc%d\n" 3

为什么PUTSR printf abc%d\n 3中的3在作为脚本运行时不明确,而在ghci中运行时则不明确?也就是说,为什么我必须在脚本中声明类型3而不是ghci

以下是ghci内部的操作:

以下是声明为Int时脚本的正确操作:

下面是当3的类型不明确时脚本的错误操作。。。对于典型的用户友好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默认为整数,只是为了让您的生活更轻松

通过启用ExtendedDefaultRules,您可以在GHC中实现类似的效果


有关这方面的详细讨论,请参阅。

GHCi只是在默认情况下启用了宽松的默认规则,使literal 5默认为整数,以使您的生活更轻松

通过启用ExtendedDefaultRules,您可以在GHC中实现类似的效果


有关这方面的详细讨论,请参阅。

您知道不需要PUTSR吗?谢谢@augustss。我没有意识到这一点。我刚试过你的建议。当然,删除putStr并不能删除literal3不明确错误。但现在,正确的表达式仅限于main=printf abc%d\n 3::Int。。。Haskell的数学简洁性是其最美丽的特征之一,因为它有助于阐明算法的本质,特别是在大量使用Hindley Milner的情况下,尽管在这种情况下无法消除数字的歧义。你知道不需要PUTSR吗?谢谢@augustss。我没有意识到这一点。我刚试过你的建议。当然,删除putStr并不能删除literal3不明确错误。但现在,正确的表达式仅限于main=printf abc%d\n 3::Int。。。Haskell的数学简洁性是其最美丽的特征之一,因为它有助于阐明算法的本质,特别是在大量使用Hindley Milner的情况下,尽管在这种情况下无法消除数字的歧义。
$ cat runmain-good
#!/usr/bin/env runghc
import Text.Printf
main = putStr (printf "abc%d\n" (3 :: Int))
$ ./runmain-good
abc3
$ 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)