【发布时间】:2015-03-21 20:25:39
【问题描述】:
我尝试将自动提升为Either 类型:纯值将是
用Right 提升,已经用Either 值id。
-- Wrapper for pure, non-Either values
newtype ConstRight a = ConstRight a
class LiftEither t e a where
liftEither :: t -> Either e a
instance LiftEither (Either e a) e a where
liftEither = id
instance LiftEither (ConstRight a) e a where
liftEither (ConstRight a) = Right a
x :: Either () (Int -> Int)
x = liftEither $ ConstRight (id :: Int -> Int)
y :: Either () (a -> a)
y = liftEither $ ConstRight id
z :: Either (a -> a) ()
z = liftEither $ Left id
但是,使用此方法只能提升单态值。这
y 和 z 的定义产生类型错误:
No instance for (LiftEither (ConstRight (a1 -> a1)) () (a -> a))
arising from a use of ‘liftEither’
The type variable ‘a1’ is ambiguous
No instance for (LiftEither (Either (a0 -> a0) b0) (a -> a) ())
arising from a use of ‘liftEither’
The type variables ‘b0’, ‘a0’ are ambiguous
这可以通过函数依赖来解决,但是ConstRight a不能确定e:
class LiftEither t e a | t -> e a where
liftEither :: t -> Either e a
我也尝试过使用关联类型,但我想不出合适的
ConstRight 实例的定义:
class LiftEither t where
type Result t
liftEither :: t -> Result t
instance LiftEither (Either e a) where
type Result (Either e a) = Either e a
liftEither = id
instance LiftEither (ConstRight a) where
type Result (ConstRight a) = Either e a -- e is not in scope
liftEither (ConstRight a) = Right a
是否可以为多态值实现这一点?
【问题讨论】: