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 ]