use*_*064 0 printf haskell type-inference
我对这些感到困惑:
我这样写的时候
main = do
putStrLn . printf "%f" $ 2.3
Run Code Online (Sandbox Code Playgroud)
它会导致
没有实例
(PrintfArg a0)
从使用所产生的printf
类型变量
a0
不明确
代码在GHCi中运行良好,当我runhaskell
在终端中使用时发生了这个错误.
所以我写
putStrLn . printf "%f" $ (2.3 :: Double)
Run Code Online (Sandbox Code Playgroud)
没关系,但我不知道原因.
不"%f"
推断2.3
属于类型Double
?
据我所知,putStrLn
有类型String -> IO()
,不能将printf
结果转换为何String
时2.3
不装饰Double
?
因为Haskell是不是一个依赖类型的语言中,价值的printf
的第一个参数(即"%f"
你的情况)没有处方的方式类型的printf
的第二个参数(2.3
在你的情况).
就其自身而言,2.3
类型是Fractional a => a
因为它是一个重载的文字.printf
的类型可能看起来有点神奇,因为它是非常多态的,因此例如printf "%s" "foo"
并且printf "%f" 2.3
都可以进行类型检查.这是通过PrintfType
和PrintfArg
类型类实现的.
总而言之printf "%f" 2.3
,类型检查器只知道2.3
某种类型a
同时具有a Fractional
和PrintfArg
实例; 但它不知道a
实际需要什么.它需要一种类型才能解析Fractional
和PrintfArg
实例.
这种情况有点类似于show . read
问题,并且您的示例在GHCi中起作用,因为Num
默认为Double
.