lew*_*urm 5 printf haskell ghc polyvariadic
我想定义一个记录器功能,例如
myPutStrLn = putStrLn . (++) "log: "
main = do myPutStrLn "hello"
Run Code Online (Sandbox Code Playgroud)
很好 现在,我想格式化与所提供的字符串printf
,这样
myPutStrLn $ printf "test %d" (23 :: Int)
Run Code Online (Sandbox Code Playgroud)
大!由于我经常使用这种模式,因此我想将其printf
纳入记录器功能:
myPrintf = logger . printf
where
-- note, this is just an example. should be
-- replaceable with any function with this
-- typesignature
logger :: String -> IO ()
logger = putStrLn . (++) "log: "
main = myPrintf "test %d" (23 :: Int)
Run Code Online (Sandbox Code Playgroud)
不幸的是,这失败了
The function `myPrintf' is applied to two arguments,
but its type `String -> IO ()' has only one
In a stmt of a 'do' block: myPrintf "test %d" (23 :: Int)
In the expression: do { myPrintf "test %d" (23 :: Int) }
In an equation for `main':
main = do { myPrintf "test %d" (23 :: Int) }
Run Code Online (Sandbox Code Playgroud)
GHC推断myPrintf :: String -> IO ()
,因此显然存在错误。我发现了有关多变量构成的一些信息,但是我无法将其应用于我的问题。我什至不确定是否能解决我的问题。
该代码也可以通过gist获得。
您可以使用 hPrintf 和 stdout 句柄来定义函数。
这样,函数 myPrintf 的结果仍然是 HPrintfType 类的实例
myPrintf:: (HPrintfType c) => String -> c
myPrintf = (hPrintf stdout) . (printf "log:%s")
main = myPrintf "test %d" (23 :: Int)
Run Code Online (Sandbox Code Playgroud)
printf 函数的多变量形式仅在您具有以下实例定义时才起作用:
(PrintfArg a, PrintfType r) => PrintfType (a -> r).
Run Code Online (Sandbox Code Playgroud)
在每个新的 PrintfArg 参数处,类型推断会返回 PrintfType 类类型(如果可能)。
为了工作,您的记录器功能将具有以下类型:
logger :: (PrintfType c) => String -> c
Run Code Online (Sandbox Code Playgroud)
但编译器将失败,因为该函数返回 IO () 而不是更通用的类型类 PrintfType。
在我看来,只有对模块 Text.Printf 进行修改才能帮助您,因为您无法创建 PrintfType 的新实例,因为某些方法被隐藏了
归档时间: |
|
查看次数: |
285 次 |
最近记录: |