Haskell 如何优雅地创建可选值列表?
考虑以下函数Haskell 如何优雅地创建可选值列表?,haskell,Haskell,考虑以下函数 annotate :: AST -> [MetaInfo] annotate (ArgDecl name nameReq maybeVal) = concat [ [m [Name] name], if nameReq then [m [Operator] "!"]] else [], case maybeVal of Just v -> [ann
annotate :: AST -> [MetaInfo]
annotate (ArgDecl name nameReq maybeVal)
= concat [
[m [Name] name],
if nameReq
then [m [Operator] "!"]]
else [],
case maybeVal of
Just v -> [annotate v]
Nothing -> []
]
...
这似乎有点优雅。有没有更好的方法来创建可能包含或不包含在其中的值列表,而不是将
concat
与空列表结合使用?正如@AJFarmar所指出的那样,只需将其清理一下就可以:
annotate :: AST -> [MetaInfo]
annotate (ArgDecl name nameReq maybeVal)
= concat
[ [m [Name] name]
, if nameReq
then [m [Operator] "!"]
else []
, case maybeVal of
Just v -> [annotate1 v]
Nothing -> []
]
借助数据中的catMaybes
,也可以更清楚地从单例/空集切换到Just/Nothing。可能
:
annotate' :: AST -> [MetaInfo]
annotate' (ArgDecl name nameReq maybeVal)
= catMaybes
[ Just (m [Name] name)
, if nameReq
then Just (m [Operator] "!")
else Nothing
, annotate1 <$> maybeVal
]
当我以这样的长代码结束时,我通常通过命名片段来清理它:
annotate :: AST -> [MetaInfo]
annotate (ArgDecl name nameReq maybeVal)
= concat [name, bang, annotation]
where
name = [m [Name] name]
bang | nameReq = [m [Operator] "!"]]
| otherwise = []
annotation = case maybeVal of
Just v -> [annotate v]
Nothing -> []
考虑到这里有一个可能
,我也可以选择catMaybes
来简化注释
定义:
annotate :: AST -> [MetaInfo]
annotate (ArgDecl name nameReq maybeVal)
= catMaybes [name, bang, annotation]
where
name = Just $ m [Name] name
bang | nameReq = Just $ m [Operator] "!"
| otherwise = Nothing
annotation = annotate <$> maybeVal
annotate::AST->[MetaInfo]
注释(ArgDecl name nameReq maybeVal)
=catMaybes[名称、bang、注释]
哪里
name=仅$m[name]name
bang | nameReq=仅$m[操作员]“!”
|否则=没有
注释=注释maybeVal
我倾向于将列表概括为任何备选方案,并利用相关功能。我发现guard condition*>…
在这种情况下非常好
annotate :: Alternative f => AST -> f MetaInfo
annotate (ArgDecl name nameReq maybeVal) =
pure (m [Name] name)
<|>
guard nameReq *> pure (m [Operator] "!")
<|>
maybe empty (pure . annotate) maybeVal
annotate::Alternative f=>AST->f MetaInfo
注释(ArgDecl name nameReq maybeVal)=
纯(m[名称]名称)
guard nameReq*>pure(m[运算符]“!”)
可能是空的(pure.annotate)可能是空的
或者,即使使用简单的列表,使用列表理解看起来也不错
annotate :: AST -> [MetaInfo]
annotate (ArgDecl name nameReq maybeVal) =
[m [Name] name]
++
[ m [Operator] "!" | nameReq ]
++
[ annotate v | Just v <- maybeVal ]
annotate::AST->[MetaInfo]
注释(ArgDecl name nameReq maybeVal)=
[m[姓名]姓名]
++
[m[操作员]“!”| nameReq]
++
[annotate v | Just v我实际上认为这很优雅唯一的问题是可读性。也许在行首加逗号会有帮助?你可能还想看看。
annotate :: Alternative f => AST -> f MetaInfo
annotate (ArgDecl name nameReq maybeVal) =
pure (m [Name] name)
<|>
guard nameReq *> pure (m [Operator] "!")
<|>
maybe empty (pure . annotate) maybeVal
annotate :: AST -> [MetaInfo]
annotate (ArgDecl name nameReq maybeVal) =
[m [Name] name]
++
[ m [Operator] "!" | nameReq ]
++
[ annotate v | Just v <- maybeVal ]