Я пытаюсь перевести на Идрис пример из Cayenne - язык с зависимыми типамиpaper.Впечатано в печатном виде в Idris
Вот то, что я до сих пор:
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
работал? .
Какое доказательство необходимо предоставить для обеспечения этой работы 'printf' со строкой времени выполнения? – is7s
@ is7s, хороший вопрос, я не знаю. Я не играл с Идрисом с этого вопроса/ответа. Я вижу некоторую идею в http://eb.host.cs.st-andrews.ac.uk/drafts/eff-tutorial.pdf, где говорится: «Верните доказательство того, что целое число находится в требуемом диапазоне вместе с самим целым» , Поэтому, я думаю, вам придется разбирать строку формата и возвращать ее с помощью доказательства, которое имеет некоторый формат. – huynhjl