地图功能不能按预期工作

时间:2016-12-03 18:02:31

标签: haskell latex

我有几个用于写入.tex文件的Haskell函数(使用HaTeX包),如下所示:

theBody :: Monad m => [ Maybe (String, String)] -> LaTeXT_ m
theBody listOfEntries = do
  maketitle
  center $ tabular Nothing [RightColumn, VerticalLine, LeftColumn] $ do
    textbf "Name" & textbf "Tel"
    let removedJusts = map fromJust listOfEntries
    map tableEntry removedJusts

tableEntry :: Monad m => (String, String) -> LaTeXT_ m
tableEntry (name, number) = do
  lnbk
  hline
  do
    textit (fromString name)
    &
    textit (fromString number)

当我运行此代码时,出现以下错误:

Couldn't match expected type ‘LaTeXT m ()’ with actual type ‘[LaTeXT_ m0]’

从我将tableEntry函数映射到我的元组列表的行开始。元组列表看起来像这样:

[("A Name", "12345"), ("Another Name", "54321"), ("Yet Another Name", "98765")]

如果我将map tableEntry removedJusts替换为:

tableEntry (removedJusts !! 0)
tableEntry (removedJusts !! 1)
tableEntry (removedJusts !! 2)

它确实将这些条目添加到我的tex文件中,因此我无法理解为什么地图功能对列表不起作用。

任何帮助表示感谢。

1 个答案:

答案 0 :(得分:2)

tableEntry (removedJusts !! 0)有效,因为它与theBody函数的返回类型(LaTeXT_ m匹配,或者扩展类型同义词LaTeXT m ())。另一方面,map tableEntry removedJusts会提供LaTeXT_ m列表,从而导致您看到的类型错误。您实际需要的是mapM_,除了映射之外,它还会将所有生成的LaTeXT m ()计算合并到一个LaTeXT m ()中:

GHCi> :t mapM_
mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m ()
theBody :: Monad m => [ Maybe (String, String)] -> LaTeXT_ m
theBody listOfEntries = do
  maketitle
  center $ tabular Nothing [RightColumn, VerticalLine, LeftColumn] $ do
    textbf "Name" & textbf "Tel"
    let removedJusts = map fromJust listOfEntries
    mapM_ tableEntry removedJusts

P.S。:一个你最终会发现有用的密切相关的函数是traverse。与mapM_不同,traverse收集而不是丢弃每个计算的结果。 (我在这里使用了mapM_因为你确实要放弃所说的结果,因为它们只是()。)

P.P.S。:使用fromJust通常不是一个好主意。如果输入列表中有theBody,它会使您的Nothing崩溃并显示一般错误消息。更好的选项包括catMaybes(来自Data.Maybe),它会默默过滤出Nothing值(例如let removedJusts = catMaybes listOfEntries),以及maybefromMaybe (后者也来自Data.Maybe),允许您选择如何处理Nothing值。