Próbuję przetłumaczyć na Idris przykład z Kajenna - język z zależnych typówpaper.Dependently typed printf w Idris
Oto co mam do tej pory:
PrintfType : (List Char) -> Type
PrintfType Nil = String
PrintfType ('%' :: 'd' :: cs) = Int -> PrintfType cs
PrintfType ('%' :: 's' :: cs) = String -> PrintfType cs
PrintfType ('%' :: _ :: cs) = PrintfType cs
PrintfType (_ :: cs) = PrintfType cs
printf : (fmt: List Char) -> PrintfType fmt
printf fmt = rec fmt "" where
rec : (f: List Char) -> String -> PrintfType f
rec Nil acc = acc
rec ('%' :: 'd' :: cs) acc = \i => rec cs (acC++ (show i))
rec ('%' :: 's' :: cs) acc = \s => rec cs (acC++ s)
rec ('%' :: _ :: cs) acc = rec cs acc -- this is line 49
rec (c :: cs) acc = rec cs (acC++ (pack [c]))
Używam List Char
zamiast String
dla formatu argumentu w celu ułatwienia z dopasowywania wzorców jak szybko wpadł złożoności z wzorzec dopasowania na String
.
Niestety pojawia się komunikat o błędzie nie jestem w stanie zrozumieć:
Type checking ./sprintf.idr
sprintf.idr:49:Can't unify PrintfType (Prelude.List.:: '%' (Prelude.List.:: t cs)) with PrintfType cs
Specifically:
Can't convert PrintfType (Prelude.List.:: '%' (Prelude.List.:: t cs)) with PrintfType cs
Gdybym skomentować wszystkie przypadki wzór meczu z 3 elementów (te z '%' :: ...
) w PrintfType
i printf
, następnie kod kompiluje (ale oczywiście nie robi nic ciekawego).
Jak naprawić mój kod, aby działał printf "the %s is %d" "answer" 42
? .
Jaki dowód należy dostarczyć, aby ten "printf" działał z łańcuchem wykonawczym? – is7s
@ is7s, dobre pytanie, nie wiem. Nie grałem z Idrisem od czasu tego pytania/odpowiedzi. Widzę jakiś pomysł w http://eb.host.cs.st-andrews.ac.uk/drafts/eff-tutorial.pdf, gdzie jest napisane _wróć dowód, że liczba całkowita jest w wymaganym zakresie wraz z liczbą całkowitą sama_ . Sądzę więc, że musiałbyś przetworzyć ciąg formatu i zwrócić go z dowodem, że ma jakiś format "Format". – huynhjl