Haskell将数据从列表转换为单个
我在Haskell写一个类似的翻译,到目前为止非常有趣。我正在进行Codegen步骤(获取解析器结果,将其打印到代码中),我尝试做的一件事是: 我有模块,我的模块有声明Haskell将数据从列表转换为单个,haskell,Haskell,我在Haskell写一个类似的翻译,到目前为止非常有趣。我正在进行Codegen步骤(获取解析器结果,将其打印到代码中),我尝试做的一件事是: 我有模块,我的模块有声明 codegen :: Module -> Either String ByteString codegen Module { what = "module", declarations = decls } = Right $ foldM (\output decl -> output ++ (codegenD
codegen :: Module -> Either String ByteString
codegen Module { what = "module", declarations = decls } = Right $ foldM (\output decl ->
output ++ (codegenDecl decl)) (empty :: ByteString) decls -- generate declarations
codegen Module { what = s } = Left $ "Bad module 'what' key " ++ s
codegenDecl :: Declaration -> Either String ByteString
codegenDecl Declaration { what = dt, name = dn, argnames = Just al, constructors = Just lc } = Right $ "Declaration " ++ dn ++ " of type " ++ dt
模式匹配变量decls
是decls::[Declaration]
,我正在使用其中一个monad进行错误跟踪。我对你的期望是什么
foldM(\output decl->
output++(codegenDecl decl))(empty::ByteString)decls
如果所有声明都正确,则返回所有bytestring,或者返回一个Left$“Error write a declaration”
但是我想我在这里遗漏了一些东西,就像打字员抱怨的那样。如果其中一个声明失败,我希望整个模块都失败。如果它们都成功了,我想将它们连接成一个ByteString
[decls] --------> Right result -------> Right $ foldM (++) accumulator result |
| ^ |
| -----------------------------------
|
|-----------> Left err ------------> Left $ err
底部的部分似乎是>>=操作符所做的,因此我认为有一种时尚的、一元的方式来做我想做的事情,而无需案例等等。我很想知道这里最好的款式是什么。
附加列表(++)::[a]->[a]->[a]
output::ByteString
codegenDecl decl::通过testring的字符串之一
输出
与(++)
的第一个参数的预期类型不匹配(除非在某个地方重新定义了它,例如在基本前奏曲中),并且codegenDecl
与(++)
的第二个参数的预期类型不匹配
此lambda应进行类型检查(使用数据中的()
。Monoid
):
\output decl->fmap(输出)(codegenDecl decl)
这并不是对这个问题的真正回答,因为它没有解决您关于foldM
的问题。。。但我甚至不会使用foldM
。我认为执行所有codegenDecl
ing,然后分别连接结果更为简洁。这将有两个好处:
ByteString
串联操作,该操作可以首先构建一个大小合适的缓冲区,然后遍历它一次以填充它。这将比重复追加更有效,重复追加必须通过testring多次提前重新访问并分配许多缓冲区
mapM
而不是foldM
,所以读者可以减少注意力,仍然可以对正在发生的事情得出正确的结论mconcat <$> mapM codegenDecl decls
mconcat mapM codegenDecl decls
关于“打字机投诉”:发生这种情况时,您应该始终发布(完整)错误消息。否则,您会强迫读者在头脑中执行类型检查,试图找出错误所在,或者试图从代码中构建MCVE——这两种方法都需要付出不平凡的努力。这会减少有人回答您问题的可能性。您想要类似于concat mapM codegenDecl decls
的内容吗?太好了,谢谢!因此,需要澄清的是,如果结果数组有多个“左错误”,mconcat实际上不会concat对吗?@rausted正确:只要codegenDecl
为其中一个decls
返回Left
,整个计算将立即中止并返回Left
。
mconcat <$> mapM codegenDecl decls