在Haskell中打印一个语法树

时间:2011-04-20 19:38:04

标签: haskell types io pretty-print

我不明白这种类型错误:

Couldn't match expected type `[t0]' with actual type `IO ()'
In the return type of a call of `printv'
In a stmt of a 'do' expression: px <- printv x
In the expression:
  do { px <- printv x;
       sep <- print ", ";
       rest <- prints xs;
       return (px : sep : rest) }

发件人:

data    Value     = IntValue     Int
                  | TruthValue   Bool
                    deriving (Eq, Show)

printv :: Value -> IO()
printv (IntValue   i) = print i
printv (TruthValue b) = print ("boolean" ++ show b)

prints :: [Value] -> [IO()]
prints  []    =  []
prints (x:xs) = do px   <- printv x
                   sep  <- print ", "
                   rest <- prints xs
                   return (px:sep:rest)

我认为每个元素(px)都会转换为IO()操作,然后将其添加到相同内容的列表中,从而生成[IO()]列表

我在这里缺少什么?通过删除打印件将其转换为字符串列表,可以正常工作。

4 个答案:

答案 0 :(得分:3)

您错过了return [] prints案例中的prints [] = return []

[()]

然而,你的版画很奇怪。它返回print,因为printv正在向控制台输出字符串,而不是返回它们。

您的意思是从import Text.PrettyPrint import Data.List data Value = VInt Int | VBool Bool deriving (Eq, Show) class Pretty a where pretty :: a -> Doc instance Pretty Value where pretty (VInt i) = int i pretty (VBool b) = text "Boolean" <+> text (show b) draw :: [Value] -> String draw = intercalate ", " . map (render.pretty) main = putStrLn $ draw [VInt 7, VBool True, VInt 42] 函数返回字符串吗?


由于您正在尝试打印一个语法树,所以这是大致正确的方法:

像这样:

*A> main
7, Boolean True, 42

运行它:

{{1}}

答案 1 :(得分:2)

仔细查看您的功能类型:

prints :: [Value] -> [IO()]

但是如果我们现在看一下prints [] = [],这是不匹配的,因为那个的类型是

prints :: [t] -> [a]

因此,您错过了使用prints [] = return [],以使其正常运行。

答案 2 :(得分:1)

如果您没有评估IO操作,则不需要do阻止。只需将IO ()视为普通类型。

prints (x:xs) = printv x : print ", " : prints xs

答案 3 :(得分:1)

您不希望prints返回IO操作数组。您希望它返回单个IO操作,该操作表示绑定在一起的每个IO操作。类似的东西:

prints xs = mapM_ (\x -> printv x >> putStr ", ") xs

除了我认为新行不会在你想要的地方结束。

有关详情,请查看mapMsequence的{​​{3}}。特别是,序列的documentation可能与您尝试的类似。

但是,我真的建议在IO函数中完成所有工作,你应该编写一个纯函数来渲染你想要的文本格式,然后打印出来。特别是,Show的{​​{1}}实例似乎是合适的。

Value

这样您就可以拨打instance Show Value where show (IntValue i) = show i show (TruthValue b) = "boolean " ++ show b 而不是print value,如果您真的想要,可以按如下方式定义printv value

prints