cen*_*980 0 haskell functional-programming
我正在尝试将String数字(例如"2 3 9 10 14")转换为的列表Maybe [Token]。我有以下代码,其中该函数parseToken将a String转换为Maybe Token。
data Token = Num Int
parseToken :: String -> Maybe Token
parseToken str = fmap Num (readMaybe str)
Run Code Online (Sandbox Code Playgroud)
为了将转换String为Maybe [Token],我在下面有以下代码:
tokenise :: String -> Maybe [Token]
tokenise str = do
let (x:xs) = words str
y <- parseToken x
ys <- parseToken xs
return (y:ys)
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用bind(>>=)函数来执行此操作。最初,我使用words函数将字符串转换为字符串列表。然后将其应用于parseToken列表的第一个元素,并将其结果(即Token值)存储在y中。但是,我不确定如何使用bind将parseToken应用于列表的其余部分。通常,如果要在考虑失败的情况下将函数应用于列表的每个元素,然后将结果合并到新列表中,那么最好的方法是什么?任何见解都表示赞赏。
您已经在这里的一个函数中合并了两个单独的关注点:
到目前为止,一切正常。不过,我建议将步骤(2)拆分为一个单独的函数,并根据它来实现顶级功能。所以:
parseTokens :: [String] -> Maybe [Token]
parseTokens [] = ...
parseTokens (x:xs) = ...
Run Code Online (Sandbox Code Playgroud)
我认为您会发现实现此目标比实现tokenise批发更容易,因为到处理时间时xs,您会发现已经有一个可以执行所需功能的函数。我建议您在实施此功能时采取行动;如果您遇到麻烦,那么也许可以尝试一个新的问题,以及为什么您认为无法取得进展就可以了。
完成此操作后,可以在现有tokenise实现中将该函数放到适当的位置:
tokenise str = do
let (x:xs) = words str
parseTokens (x:xs)
Run Code Online (Sandbox Code Playgroud)
当然,在这一点上,没有理由对这样的结果进行模式匹配words,因为无论如何您都打算传递结果:
tokenise str = do
let xs = words str
parseTokens xs
Run Code Online (Sandbox Code Playgroud)
然后大多数人会内联xs,
tokenise str = do
parseTokens (words str)
Run Code Online (Sandbox Code Playgroud)
删除多余的do,
tokenise str = parseTokens (words str)
Run Code Online (Sandbox Code Playgroud)
并使其毫无意义。
tokenise = parseTokens . words
Run Code Online (Sandbox Code Playgroud)