gpt4 book ai didi

haskell - Text.Printf.printf 的函数组合

转载 作者:行者123 更新时间:2023-12-04 21:47:25 25 4
gpt4 key购买 nike

我想定义一个记录器函数,比如

myPutStrLn = putStrLn . (++) "log: "
main = do myPutStrLn "hello"

这很好。现在我想用 printf 格式化提供的字符串, 像这样
myPutStrLn $ printf "test %d" (23 :: Int)

伟大的!因为我经常有这种模式,所以我想考虑 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)

不幸的是,这失败了
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) }

GHC 推断 myPrintf :: String -> IO () ,所以显然有问题。我发现了一些关于 Polyvariadic composition 的信息,但我无法将此应用于我的问题。我什至不确定它是否能解决我的问题。

该代码也可通过 gist 获得.

最佳答案

您可以使用 hPrintf 和 stdout 句柄来定义您的函数。

像这样,函数 myPrintf 的结果仍然是 HPrintfType 类的实例

myPrintf::  (HPrintfType c) => String -> c
myPrintf = (hPrintf stdout) . (printf "log:%s")

main = myPrintf "test %d" (23 :: Int)

printf 函数的多变量形式仅因为您具有此实例定义而起作用:
(PrintfArg a, PrintfType r) => PrintfType (a -> r).

在每个新的 PrintfArg 参数中,如果可能,类型推断返回一个 PrintfType 类类型。

为了工作,您的记录器功能将具有以下类型:
logger :: (PrintfType c) => String -> c

但是编译器会失败,因为函数返回一个 IO () 而不是更通用的类型类 PrintfType。

在我看来,只有对模块 Text.Printf 的修改可以帮助您,因为您无法创建 PrintfType 的新实例,因为某些方法是隐藏的

关于haskell - Text.Printf.printf 的函数组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12123082/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com