我正在尝试用PureScript编写类似Redux的存储。
我为每个动作定义了Action
类型类和代数数据类型,以划分为更小的模块。
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
为什么会出现此错误?我应该如何实现这样的更新功能?
答案 0 :(得分:0)
此处的问题是您在值Action a => a
上匹配,就像它是Foo
一样,因此类型错误。
如果要使用类来解决问题,那么方法是将操作作为类的一部分,而不是不同类型的数据构造函数:
class Thing a
update :: a -> String
reset :: a -> Unit
然后,您可以使用update
,reset
,Foo
或您实施{{1}的任何类型值来致电Bar
或Baz
} instance for。
如果问题是你要表示这些事情可以执行的不同操作集,那么你也可以使用子类:
Thing
我不确定我是否完全理解你在这里尝试做什么,所以也许这不是你真正想要做的事情,但希望能给你一些想法。