假设我想使用类型类进行某种表示抽象来编写数独求解器。因此,我想为行和矩阵创建一个类型类:
```html
很明显,我还可以添加更多内容,但仅这些函数就足以让我陷入麻烦。现在假设我想要使用嵌套列表实现这个功能。尝试如下:
让我陷入麻烦的情况:
第二次尝试:
```html
假设我想使用类型类进行某种表示抽象来编写数独求解器。因此,我想为行和矩阵创建一个类型类:
```{-# LANGUAGE FlexibleInstances #-}
class Row r where
(!) :: r -> Int -> Int
class Sudoku a where
row :: (Row r) => Int -> a -> r
很明显,我还可以添加更多内容,但仅这些函数就足以让我陷入麻烦。现在假设我想要使用嵌套列表实现这个功能。尝试如下:
instance Row r => Sudoku [r] where
row n s = s !! (n - 1)
让我陷入麻烦的情况:
Couldn't match expected type `r1' against inferred type `r'
`r1' is a rigid type variable bound by
the type signature for `row' at 96b.hs:7:14
`r' is a rigid type variable bound by
the instance declaration at 96b.hs:12:13
In the expression: s !! (n - 1)
In the definition of `row': row n s = s !! (n - 1)
In the instance declaration for `Sudoku [r]'
第二次尝试:
instance Row [Int] where
r ! n = r !! (n - 1)
instance Sudoku [[Int]] where
row n s = s !! (n - 1)
情况不会更好:
Couldn't match expected type `r' against inferred type `[Int]'
`r' is a rigid type variable bound by
the type signature for `row' at 96b.hs:8:14
In the expression: s !! (n - 1)
In the definition of `row': row n s = s !! (n - 1)
In the instance declaration for `Sudoku [[Int]]'
我似乎漏掉了一些东西。如何正确地建模像这样的简单场景?
Sudoku a
,RowType a
必须是Row
的实例? - Lambdageekrow :: Row (RowType a) => Int -> a -> RowType a
,如果我没记错的话。 - fuzRow r => [r]
,对于某些行类型r
,我可以获得任何行类型r2
的Row r2 => r2
,因为在类定义中它们之间没有依赖关系。但是你的实例只展示了如何获取 _相同类型的行_,所以它比要求的多态性要少。 - hammar