为什么这个类型 class 实例无法统一?
Why is this type class instance failed to unify?
我正在尝试用 PureScript 编写类似 Redux 的商店。
我为每个动作定义了 Action
类型 class 和代数数据类型以划分为更小的模块。
class Action a
data FooAction
= UpdateFoo String
| ResetFoo
data BarAction
= UpdateBar Int
| ResetBar
data ResetAll = ResetAll
instance fooAction :: Action FooAction
instance barAction :: Action BarAction
并定义了一些状态类型和更新函数。更新功能可能会收到所有类型的操作。
newtype Foo = Foo String
newtype Bar = Bar Int
updateFoo :: forall a. (Action a) => a -> Foo -> Foo
updateFoo a foo =
case a of
UpdateFoo str -> Foo str
ResetFoo -> Foo ""
ResetAll -> Foo ""
_ -> foo
updateBar :: forall a. (Action a) => a -> Bar -> Bar
updateBar a bar =
case a of
UpdateBar num -> Bar num
ResetBar -> Bar 0
ResetAll -> Bar 0
_ -> bar
但是此代码会产生 TypesDoNotUnify 错误。
Could not match type
FooAction
with type
a0
while checking that expression case a of
(UpdateFoo str) -> Foo str
ResetFoo -> Foo ""
ResetAll -> Foo ""
_ -> foo
has type Foo
in value declaration updateFoo
where a0 is a rigid type variable
为什么会出现这个错误?我应该如何实现这样的更新功能?
这里的问题是您在匹配值 Action a => a
时就好像它是 Foo
,因此会出现类型错误。
如果您想使用 classes 来解决问题,方法是将操作作为 class 的一部分,而不是不同类型的数据构造函数:
class Thing a
update :: a -> String
reset :: a -> Unit
然后你可以调用 update
或 reset
与 Foo
, Bar
, Baz
或你实现 Thing
实例。
如果问题是您想表示这些东西可以执行的不同操作集,那么您也可以使用子class:
class Thing a <= SubThing a
act :: a -> Unit
虽然我不确定我是否完全理解您在这里尝试做的事情,所以也许这并不是您真正想要的,但希望能给您一些想法。
我正在尝试用 PureScript 编写类似 Redux 的商店。
我为每个动作定义了 Action
类型 class 和代数数据类型以划分为更小的模块。
class Action a
data FooAction
= UpdateFoo String
| ResetFoo
data BarAction
= UpdateBar Int
| ResetBar
data ResetAll = ResetAll
instance fooAction :: Action FooAction
instance barAction :: Action BarAction
并定义了一些状态类型和更新函数。更新功能可能会收到所有类型的操作。
newtype Foo = Foo String
newtype Bar = Bar Int
updateFoo :: forall a. (Action a) => a -> Foo -> Foo
updateFoo a foo =
case a of
UpdateFoo str -> Foo str
ResetFoo -> Foo ""
ResetAll -> Foo ""
_ -> foo
updateBar :: forall a. (Action a) => a -> Bar -> Bar
updateBar a bar =
case a of
UpdateBar num -> Bar num
ResetBar -> Bar 0
ResetAll -> Bar 0
_ -> bar
但是此代码会产生 TypesDoNotUnify 错误。
Could not match type
FooAction
with type
a0
while checking that expression case a of
(UpdateFoo str) -> Foo str
ResetFoo -> Foo ""
ResetAll -> Foo ""
_ -> foo
has type Foo
in value declaration updateFoo
where a0 is a rigid type variable
为什么会出现这个错误?我应该如何实现这样的更新功能?
这里的问题是您在匹配值 Action a => a
时就好像它是 Foo
,因此会出现类型错误。
如果您想使用 classes 来解决问题,方法是将操作作为 class 的一部分,而不是不同类型的数据构造函数:
class Thing a
update :: a -> String
reset :: a -> Unit
然后你可以调用 update
或 reset
与 Foo
, Bar
, Baz
或你实现 Thing
实例。
如果问题是您想表示这些东西可以执行的不同操作集,那么您也可以使用子class:
class Thing a <= SubThing a
act :: a -> Unit
虽然我不确定我是否完全理解您在这里尝试做的事情,所以也许这并不是您真正想要的,但希望能给您一些想法。