2016-02-02 20 views
0

我有下面的代碼,使用this tabulation libraryText.Tabular.Table類型錯誤 - 類型系統向我詢問的是什麼?

{-# 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構造函數應用於值列表,然後將它們放入構造函數的構造函數中即可獲得整行(或列)的值,但這些錯誤似乎表明列表(和數據)我作爲參數傳遞給Header構造函數已經需要爲Header s。因此,我對這裏的類型系統告訴我什麼以及如何得到我想要的東西感到困惑。

從本質上講,這個表應該是這個樣子:

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

回答

1

我花了一段時間才能找到這一個,因爲在你的函數的定義沒有問題:它的類型聲明是錯誤的。

讓我們一起來看看Table定義:

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

列標題和行頭型paramater已經扭曲的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類型是可能使用了兩次。

相關問題