假设我将数据类型定义如下:
data OP = Plus | Minus | Num Int deriving (Show, Eq)
然后我会列出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)
然后我要显示[OP]
列表,用新行分隔。我已经轻松完成了字符串列表,但不确定如何处理数据类型列表。
我有以下结构作为起点:
showOp :: [OP] -> String
showOp [] = []
showOp (o:os) = (putStr o):'\n':(showOp os)
我知道最后一行是错的。我试图在第一部分中返回[Char]
,然后是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.
另外,我不确定Num Int
类型的输出需要如何不同,因为我需要显示类型名称和值。
这样的示例i / o类似于:
in:
getOp ["7","+","4","-","10"]
out:
Num 7
Plus
Num 4
Minus
Num 10
答案 0 :(得分:4)
您需要查看正在使用的函数和对象的类型。 Hoogle是获取功能签名的绝佳资源。
首先,putStr
的签名是
putStr :: String -> IO ()
但您的代码有putStr o
,其中o
不是字符串,结果不应该是IO ()
。您真的希望showOp
打印 Op
,还是只为它创建一个多行字符串?
如果是前者,则需要showOp
的签名来反映:
showOp :: [Op] -> IO ()
然后你可以使用一些do
- 符号来完成这个功能。
我会为您指定的类型签名编写解决方案。由于showOp
应返回String
而putStr
返回IO ()
,因此我们无法在任何地方使用putStr
。请注意,String
只是[Char]
的类型同义词,这就是我们可以将String
视为列表的原因。
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
showo
和showos
都是String
:show
和showOp
都返回String
。
我们可以使用cons操作:
将单个字符添加到字符列表中。我们可以使用追加运算符++
附加两个字符串列表。
现在你可能想要另一个功能
printOp :: [Op] -> IO ()
printOp xs = putStr $ showOp xs
答案 1 :(得分:3)
怎么样:
showOp = putStrLn . unlines . map show
请注意,您的数据构造函数OP
已经是Show
的实例。因此,您实际上可以map show
进入包含OP
类型成员的数组。在那之后,事情变得非常轻松。
快速的几个笔记......
你可能想要:
getOp :: [String] -> [OP]
getOp [] = []
getOp (x:rest)
| x == "+" = Plus:(getOp rest)
| x == "-" = Minus:(getOp rest)
| isInfixOf "Num" x == True = Num (read (drop 4 x) :: Int):(getOp rest)
| otherwise = (getOp rest)
而不是你拥有的。您的程序有语法错误...
接下来,您要提供的输入可能是
["Num 7","+","Num 4","-","Num 10"]
?我猜这是一个错字。