Ceci est un problème de challenge plus qu'un problème utile (j'ai passé quelques heures dessus). Compte tenu de certaines fonctions,Comment écrire une famille de fonctions printf (impression de débogage, etc.) dans Haskell
put_debug, put_err :: String -> IO()
put_foo :: String -> StateT [String] m()
Je veux écrire une fonction printf généralisée, appelez-GPRINT, de sorte que je peux écrire
pdebug = gprint put_debug
perr = gprint put_err
pfoo = gprint put_foo
puis utilisez pdebug
, perr
et pfoo
comme printf
, par exemple ,
pdebug "Hi"
pdebug "my value: %d" 1
pdebug "two values: %d, %d" 1 2
Je n'arrive pas à trouver une classe suffisamment générale. Mes tentatives ont été des choses comme (pour ceux qui connaissent Printf
, ou approche de la fonction variadique Oleg)
class PrintfTyp r where
type AppendArg r a :: *
spr :: (String -> a) -> String -> [UPrintf] -> AppendArg r a
ou
class PrintfTyp r where
type KRetTyp r :: *
spr :: (String -> KRetTyp r) -> String -> [UPrintf] -> r
Les deux sont trop difficiles à écrire des instances de base pour: il n'y a pas un bon choix pour r
pour la première approche (et, son type n'est pas reflété dans la famille de types indexés non-injectifs AppendArg
), et dans la deuxième approche, on finit par écrire instance PrintfTyp a
qui semble faux (correspond à trop de types).
Encore une fois, c'est juste un problème de défi: faites-le seulement si c'est amusant. Je serais certainement curieux de connaître la réponse si. Merci!!
Oui , Je voulais éviter les terminateurs. Je serais plus intéressé à ne soutenir qu'un seul argument, c'est-à-dire ne pas soutenir le cas 'pdebug 'pas d'arguments" '. Merci quand même. – gatoatigrado