我有几个用于写入.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文件中,因此我无法理解为什么地图功能对列表不起作用。
任何帮助表示感谢。
答案 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
),以及maybe
和fromMaybe
(后者也来自Data.Maybe
),允许您选择如何处理Nothing
值。