我正在尝试将来自《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
作为format参数,以便更容易地进行模式匹配,因为在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
如果我在
PrintfType
和printf
中注释掉所有具有3个元素的模式匹配案例(即带有'%' :: ...
的案例),那么代码就可以编译(但显然不会执行任何有趣的操作)。我该如何修复我的代码,以便
printf "the %s is %d" "answer" 42
能够正常工作?
printf
能够使用运行时字符串? - is7s