Text.Tabular.Table类型错误 - 系统询问的类型是什么?

时间:2016-02-02 04:42:28

标签: haskell formatting

我有以下代码,使用this tabulation library

{-# LANGUAGE NoImplicitPrelude, OverloadedStrings #-}

import ClassyPrelude
import qualified Text.Tabular as T

data Category = Age | Gender | Usual | Years
  deriving (Show, Read, Eq, Enum, Bounded)

 tabulate :: Text -> [[Int]] -> T.Table (T.Header Int) (T.Header Text) Int
 tabulate lbl tab = T.Table (T.Group T.NoLine (map T.Header leftcoll)) (T.Group T.DoubleLine [T.Header lbl, T.Header "All", T.Header "Cluster0", T.Header "Cluster1"]) rest
   where leftcoll = map (`indexEx` 0) tab
         rest = map (drop 1) tab

当我尝试编译它时,我收到以下错误:

Couldn't match type ‘Int’ with ‘T.Header Int’
Expected type: [T.Header Int]
  Actual type: [Int]
In the second argument of ‘map’, namely ‘leftcoll’
In the second argument of ‘T.Group’, namely
  ‘(map T.Header leftcoll)’


Couldn't match expected type ‘T.Header Text’
            with actual type ‘Text’
In the first argument of ‘T.Header’, namely ‘lbl’
In the expression: T.Header lbl

我完全不知道为什么会这样。从the Table type documentation and example开始,我似乎只需要将Header构造函数应用于值列表,然后将它们放在Group构造函数中以获取整行(或列)值,但是那里的错误似乎表明我作为参数传递给Header构造函数的列表(和数据)已经需要Header s。因此,我对类型系统在这里告诉我什么以及如何得到我想要的东西感到困惑。

基本上,表格看起来应该是这样的:

Foo All Cluster0 Cluster1
=========================
1   10  3        7
2   11  10       1
....

1 个答案:

答案 0 :(得分:1)

我花了一段时间才找到这个,因为你的函数定义没有问题:它是错误的类型声明。

让我们来看看Table的定义:

data Table rh ch a = Table (Header rh) (Header ch) [[a]]

列标题和行标题类型参数已在Header类型中变形,因此无需再次执行此操作。

而不是定义:

tabulate :: Text -> [[Int]] -> T.Table (T.Header Int) (T.Header Text) Int

你可以定义:

tabulate :: Text -> [[Int]] -> T.Table Int Text Int

为了调试这类事情,我通常会将表达式的一部分提取到where子句,以及一个类型注释,告诉编译器每个表达式应该是什么。这通常会让我得到更好的错误消息。例如,在这里,我提取了:

where tagada :: [T.Header Int]
      tagada = map T.Header leftcoll

在错误中,我可以阅读:

Expected type: [T.Header (T.Header Int)]
  Actual type: [T.Header Int]

当我意识到Header类型可能被使用了两次时。