如何在 Haskell 中打印自定义数据类型的名称和值

cHa*_*Ham 2 haskell types function show

假设我定义了一个数据类型如下:

data OP = Plus | Minus | Num Int     deriving (Show, Eq)
Run Code Online (Sandbox Code Playgroud)

然后我获取 , 的列表strings,并获取它们各自OP值的列表,如下所示:

getOp :: [String] -> [OP]
getOp [] = []
getOp (x:rest)
        | x == "+" = Plus:(getOp rest)
        | isInfixOf "Num" x == True = Num (read (drop 4 x) :: Int):(getOp rest)
        | otherwise = "-" = Minus:(getOp rest)
Run Code Online (Sandbox Code Playgroud)

然后我想显示[OP]列表,用新行分隔。我已经用字符串列表轻松完成了它,但不确定如何处理数据类型列表。

我有以下结构作为起点:

showOp :: [OP] -> String
showOp [] = []
showOp (o:os) = (putStr o):'\n':(showOp os)
Run Code Online (Sandbox Code Playgroud)

我知道最后一行是错误的。我试图[Char]在第一部分返回 a ,然后是 a Char,然后是递归调用。我为最后一行(见下文)尝试了一些其他变体,但没有成功。

showOp o = show o  (works but not what I need. It shows the whole list, not each element on a new line

showOp o = putStrLn (show o)   (epic fail)

showOp o 
    | o == "+" = "Plus\n":(showOp os)
    | more of  the same. Trying to return a [Char] instead of a Char, plus other issues.
Run Code Online (Sandbox Code Playgroud)

另外,我不确定类型的输出需要如何不同Num Int,因为我需要显示类型名称和值。

对此的示例 i/o 将类似于:

在:

getOp ["7","+","4","-","10"]
Run Code Online (Sandbox Code Playgroud)

出去:

Num 7
Plus
Num 4
Minus
Num 10
Run Code Online (Sandbox Code Playgroud)

cro*_*eea 5

您需要查看正在使用的函数和对象的类型Hoogle是获取函数签名的绝佳资源。

首先,签名putStr

putStr :: String -> IO ()
Run Code Online (Sandbox Code Playgroud)

但是您的代码有putStr o, whereo不是字符串,结果不应该是IO (). 你真的要showOp打印Op,或只是让为它多行字符串?

如果是前者,您需要的签名showOp来反映:

showOp :: [Op] -> IO ()
Run Code Online (Sandbox Code Playgroud)

然后你可以使用一些do-notation 来完成这个功能。

我将为您的给定类型签名编写一个解决方案。由于showOpshould return aStringputStr返回 an IO (),我们不会在putStr任何地方使用。请注意,这String只是 的类型同义词[Char],这就是我们可以将Strings 视为列表的原因。

showOp :: [Op] -> String
showOp [] = [] -- the empty list is a String
showOp (o:os) = showo ++ ('\n' : showos)
   where showo = (show o) -- this is a String, i.e. [Char]
         showos = showOp os -- this is also a String
Run Code Online (Sandbox Code Playgroud)

两者showoshowosStringS:都showshowOp回报String秒。我们可以使用 cons 操作将单个字符添加到字符列表中:。我们可以使用 append operator 附加两个字符串列表++

现在你可能想要另一个功能

printOp :: [Op] -> IO ()
printOp xs = putStr $ showOp xs
Run Code Online (Sandbox Code Playgroud)