Я пытаюсь перевести на Идриса пример из Cayenne - языка с зависимыми типами .
Вот что я до сих пор:
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]))
Я использую List Char
вместо String
для аргумента формата, чтобы облегчить сопоставление с шаблоном, так как я быстро столкнулся с сложностью с сопоставлением шаблонов на String
.
К сожалению, я получаю сообщение об ошибке, о котором я не могу понять:
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
Если я прокомментирую все случаи сопоставления шаблонов с 3 элементами (те, что с '%' :: ...
) в PrintfType
и printf
, тогда компиляция кода (но, очевидно, не делает ничего интересного).
Как исправить мой код, чтобы printf "the %s is %d" "answer" 42
работал?