我正在做Haskell Datentyp作业,并尝试了一整天解决这个问题。
问题是这样的。
使用此Datentyp,并且只允许使用一个函数tokenize
,不允许使用库中的其他函数。
data Token = Text String
| Placeholder String
deriving (Eq, Show)
tokenize :: String -> [Token]
大括号是占位符的标志
结果应如下所示:
当我们输入
"Hallo {name}, {xyz}."
应该给出
[Text "Hallo ", Placeholder "name", Text ", ", Placeholder "xyz", Text "."]
我已经尝试了整整一天,只有“文本输出”或“占位符”是可以的,但是我有几个问题:
如何处理大括号{}
如何使用模式匹配来匹配“ {longtext ...}”
由于Datentype
[token]
,tokenize (x: xs) = x :[ Text (xs:[])]
不起作用,因此如何处理如何将逗号和它们全部组合在一起,仅使用
[token]
类型的结果函数,我尝试了++和:,但是它们均报告错误。根据4,除此作业外,还有一个常见问题:使用Datentype时,结果类型与输入类型不匹配时,如何使用递归。
这是我答案的最后一版,距离还很远
data Token = Text String
| Placeholder String
deriving (Eq, Show)
tokenize :: String -> [Token]
tokenize [] = []
tokenize ('{':x:xs) = [ Placeholder (x:xs)]
tokenize (x: xs) = [ Text (x:xs)]
otherwise = error "TODO: Implementierung vervollstaendigen"
结果应如下所示:
当我们输入
"Hallo {name}, {xyz}."
应该给出
[Text "Hallo ", Placeholder "name", Text ", ", Placeholder "xyz", Text "."]
假设所有输入都没有内部括号,并用大括号正确地表示{}
最佳答案
在现实世界中,您可能想使用像Parsec这样的库。但是对于家庭作业,可能需要执行以下操作:
data Token = Text String
| Placeholder String
deriving (Eq, Show)
tokenize :: String -> [Token]
tokenize xs = parseText "" xs
parseText :: String -> String -> [Token]
parseText text ('{':xs) = Text text : parsePlaceholder "" xs
parseText text (x:xs) = parseText (text ++ [x]) xs
parseText text "" = [Text text]
parsePlaceholder :: String -> String -> [Token]
parsePlaceholder name ('}':xs) = Placeholder name : parseText "" xs
parsePlaceholder name (x:xs) = parsePlaceholder (name ++ [x]) xs
parsePlaceholder name "" = [Text name]
main :: IO ()
main = print (tokenize "Hallo {name}, {xyz}.")
与其立即研究代码,不如尝试只复制
parseText
和parsePlaceholder
的类型签名,以查看是否可以自己实现。几点批评:
追加到链表的末尾(就像我对
text ++ [x]
和name ++ [x]
所做的那样)不是很有效。一种可能的方法是在前面加上((:)
),最后再做一次reverse
。tokenize "{foo}"
返回[Text "",Placeholder "foo",Text ""]
,这不是很好,您可能需要合并以下帮助函数:createText "" = []
createText text = [Text text]
关于haskell - 我该如何仅使用一个函数来解决此数据类型问题,最好使用模式匹配,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56312665/