Idris2/tests/idris2/perf010/Printf.idr
Edwin Brady dd95a549d5
Fix performance regression #1991 (#1995)
* Normalise types fully at the REPL

It was a bit odd that we only normalised the scope of function types and
not the arguments, and I can't remember the reason for that if there
even was one.

* Better way of using nf_metavars_threshold

If a term is getting big and probably needs normalising, we now have a
sizeLimit flag in quote, so we can use that instead of checking the size
afterwards. This is a handy heuristic for speeding up unification when
there's a term with lots of suspended computation. Fixes #1991
2021-10-11 23:53:52 +01:00

39 lines
1.3 KiB
Idris

module Printf
import Prelude
import Data.String
data Arg
= AInt Arg
| AOther Char Arg
| AEnd
buildArg : List Char -> Arg
buildArg fmt = case fmt of
'%' :: 'i' :: fmtTail => AInt (buildArg fmtTail)
c :: fmtTail => AOther c (buildArg fmtTail)
Nil => AEnd
argToType : Arg -> Type -> Type
argToType a result = case a of
AInt fmtTail => Int -> argToType fmtTail result
AOther _ fmtTail => argToType fmtTail result
AEnd => result
-- PrintfType "foo" result = result
-- PrintfType "%i\n" result = Int -> result
-- etc
PrintfType : String -> Type -> Type
PrintfType fmt result = argToType (buildArg (unpack fmt)) result
sprintf : (fmt : String) -> PrintfType fmt String
sprintf fmt = go "" (buildArg (unpack fmt)) where
go : String -> (arg : Arg) -> argToType arg String
go strTail arg = case arg of
AInt fmtTail => \i : Int => go (strTail ++ show i) fmtTail
AOther c fmtTail => go (strTail ++ singleton c) fmtTail
AEnd => strTail
test : ?result
test = sprintf "%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i"