2010-08-06 89 views
2

我在Haskell中玩耍試圖獲得它的掛鉤。我遇到了我的類型類問題。我想要做的是通過定義類和方法來創建一個通用的a *模塊,然後我試圖在程序中使用它們。我的問題是,當我試圖讓我的專欄的數據類型我的董事會類的一個實例的列表(代表地圖),我發現了以下錯誤:自定義類型和類的實例列表

Illegal instance declaration for `Board [Box]' 
    (All instance types must be of the form (T a1 ... an) 
    where a1 ... an are type *variables*, 
    and each type variable appears at most once in the instance head. 
    Use -XFlexibleInstances if you want to disable this.) 
In the instance declaration for `Board [Box]' 

我一直在谷歌上搜索周圍這是一個解決方案,但到目前爲止,我只找到了一個描述解決方案的頁面,我在這裏無法理解:http://www.haskell.org/haskellwiki/List_instance。它描述瞭如何使用從上面的錯誤消息生成的XFlexibleInstances,但是,當我嘗試使用列表的一個元素作爲Box數據類型時,出現錯誤消息。

Couldn't match expected type `t' against inferred type `Box' 
    `t' is a rigid type variable bound by 
     the type signature for `!!' at <no location info> 

我不知道這是我做的一些奇怪的錯誤還是如果我的設計根本不是一個好的錯誤。相關的代碼是在這裏:

class Tile a where 
    tilePosition :: a -> (Int, Int) 
    tileStatus :: a -> Status 

董事會類應該是瓷磚的列表(或其中的一些集合)

class Board b where 
    surroundingTiles :: Tile t => b -> (Int, Int) -> [t] 
    startingPosition :: b -> Maybe (Int, Int) 
    targetPosition :: b -> Maybe (Int, Int) 
    (!!)    :: Tile t => b -> (Int, Int) -> Maybe t 

這似乎編譯,但在另一個文件中,我儘量讓這些類的實例是我得到的錯誤

instance Board [Box] where 
    boxes !! pos = foldl (\acc b -> if boardPos b == pos then Just b else acc) Nothing boxes 
    ... 

任何提示在正確的方向將不勝感激。

回答

1

對於[Box]功能!!類型必須Tile t => [Box] -> (Int, Int) -> Maybe t,意爲每種類型的t這是你需要能夠得到一個t[Box]Tile一個實例。

但是,您的實施類型爲[Box] -> (Int, Int) -> Maybe Box,這意味着您只能從[Box]中獲得Box,因此不起作用。

,你可以做些什麼來得到你想要的東西是這樣的:

class Board b where 
    surroundingTiles :: Tile t => b t -> (Int, Int) -> [t] 
    startingPosition :: Tile t => b t -> Maybe (Int, Int) 
    targetPosition :: Tile t => b t -> Maybe (Int, Int) 
    (!!)    :: Tile t => b t -> (Int, Int) -> Maybe t 

instance Board [] where 
    ... 

這樣,您就可以使用瓷磚作爲董事會的任何實例的名單別的也委員會(名單,但你可以因爲所有功能都需要t作爲Tile的一個實例)。

如果你需要說「瓷磚的名單瓷磚的董事會」沒有也使所有其他列表成板,則需要啓用多參數的類型類,讓你可以說這樣的話:

class Tile t => Board b t where 
    surroundingTiles :: b t -> (Int, Int) -> [t] 
    startingPosition :: b t -> Maybe (Int, Int) 
    targetPosition :: b t -> Maybe (Int, Int) 
    (!!)    :: b t -> (Int, Int) -> Maybe t 

instance Board [Tile] Tile where 
    ... 
+0

哇,非常感謝您的詳細解答。你給的第一個例子足以讓我繼續。 – Kuxi 2010-08-06 15:21:39