我目前在使用我的数据类型处理这段代码时遇到了一些问题。我使用
时工作正常 type Pos = (Int, Int)
然而我需要使用
data Pos = Pos (Int, Int) deriving (Show, Eq)
。
对于其余的代码,我已经能够将其更改为(Pos(x,y))
,但是对于这一个函数,它正在抛出此错误消息。
* No instance for (Ord Pos) arising from a use of `minimum'
* In the second argument of `(.)', namely `minimum'
In the expression: snd . minimum
In the expression:
snd . minimum $ [(score p, p) | p <- allBlanks puzzle]
这是我的功能:
blankX2 puzzle =
snd
. minimum $
[(score p, p) | p <- allBlanks puzzle] where
score (Pos(y,x)) = rowScore y + colScore x + sqScore (div x 3, div y 3)
rowScore r = blanksInBlock (row r puzzle)
colScore c = blanksInBlock (column c puzzle)
sqScore sq = blanksInBlock (square sq puzzle)
答案 0 :(得分:4)
首先说的是,尽管与你的问题无关:不要在data
中包装元组,最好使它们成为数据类型的字段。在这种情况下,您还希望使字段严格,以提高性能:
data Pos = Pos { xPosition, yPosition :: !Int }
deriving (Show, Eq)
现在,您还需要一个Ord
实例。嗯,最简单的方法是将其添加到deriving
列表中!
data Pos = Pos { xPosition, yPosition :: !Int }
deriving (Show, Eq, Ord)
或者,您也可以自己定义它,也许是因为您需要与标准排序不同的顺序。要做到这一点,你要写
instance Ord Pos
然后编译器会抱怨:
warning: [-Wmissing-methods]
• No explicit implementation for
either ‘compare’ or ‘<=’
• In the instance declaration for ‘Ord Pos’
|
3 | instance Ord Pos
| ^^^^^^^
好的,所以我们最好添加其中一种方法。 <=
更容易理解,但compare
更直接涵盖所有情况,因此建议使用。要查看您需要做什么,请从存根开始:
instance Ord Pos where
compare = _
GHC回答:
• Found hole: _ :: Pos -> Pos -> Ordering
• In the expression: _
In an equation for ‘compare’: compare = _
In the instance declaration for ‘Ord Pos’
• Relevant bindings include
compare :: Pos -> Pos -> Ordering
(bound at /tmp/wtmpf-file6330.hs:4:3)
因此,您需要将compare
实现为具有该签名的函数。
答案 1 :(得分:3)
您的Pos
数据类型必须是Ord
类型类的实例才能由minimum
使用。该类型类提供比较函数,例如<
。只需在Ord
和Show
之后添加Eq
即可让GHC自动为您提供必要的功能。