(使用注释更容易复制和粘贴)
--Say I have the following monad:
{-# LANGUAGE GADTs, FlexibleInstances #-}
data Instruction b where
Write :: a -> Instruction ()
Write2 :: (a,a) -> Instruction ()
Read :: Instruction a
Read2 :: Instruction (a,a)
Bind :: Instruction a -> (a -> Instruction b) -> Instruction b
Return :: a -> Instruction a
instance Monad Instruction where
(>>=) = Bind
return = Return
--And the following class:
class Box a where
write :: a -> Instruction ()
read :: Instruction a
instance Box Int where
write = Write
read = Read
instance Box Float where
write = Write
read = Read
instance (Box a,Box b) => Box (a,b) where
write (a,b) = do
write a
write b
read = do
a <- Read
b <- Read
return (a,b)
instance (Box a) => Box (a,a) where
write = Write2
read = Read2
--Now, this works kind of fine, as long as I do not use the overlap:
test = do
let i = 0 :: Int
let f = 0 :: Float
write (i,f)
--But i get an overlapping instance for the following (understandably):
write (i,i)
是否有可能编写这种会做“正确的事情”的类?也就是说,我如何更改程序以选择正确的实例。
我想我知道一种运行时解决方案,但这不会那么好。
我见过重写规则,这是一个好的解决方案吗?