传递给printf时,在重载的文字上键入需要的注释

时间:2016-03-21 03:07:33

标签: haskell printf type-inference

我对这些感到困惑:

当我这样写的时候

main = do
    putStrLn . printf "%f" $ 2.3

会导致

  

使用(PrintfArg a0)

时,printf没有任何实例      

类型变量a0不明确

代码在GHCi中运行良好,当我在终端中使用runhaskell时发生此错误。

所以我写了

putStrLn . printf "%f" $ (2.3 :: Double)

没关系,但我不知道原因。

不要"%f"推断2.3属于Double类型?

据我所知,putStrLn的类型为String -> IO()printf的结果可以在{{1}时转换为String没有2.3装饰?

1 个答案:

答案 0 :(得分:5)

因为Haskell不是依赖类型的语言,printf的第一个参数的(即您的案例中为"%f")无法处方printf第二个参数的类型(在您的情况下为2.3)。

2.3的类型Fractional a => a本身就是printf "%s" "foo",因为它是overloaded literalprintf's type可能看起来有点神奇,因为它是非常多态的,所以printf "%f" 2.3printf "%f" 2.3都可以进行类型检查。这是通过PrintfTypePrintfArg类型类实现的。

总而言之,在2.3中,类型检查器只知道a是某种类型Fractional同时包含PrintfArga实例;但它并不知道Fractional实际需要什么。它需要一种类型,以便可以解析PrintfArgNum个实例。

这种情况与show . read问题有些类似,由于Double defaultingconsole.next();,您的示例在GHCi中有效。