我们说我们有三个对象:
MainObj {
someProp: false
toggleSomeProp: function () {
if (this.someProp)
this.someProp = false
else
this.someProp = true
}
...
}
FirstObj {
someOtherProp: ...
doSomethingWithOtherProp: function () {...}
...
}
SecondObj {
state: null
setState: function (s) {
this.state = s
}
getState: function() {
return this.state
}
...
}
FirstObj
和SecondObj
从someProp
继承toggleSomeProp
和MainObj
,并使用自己的属性和方法对其进行扩展。 SecondObj
使用state属性(和get / set方法)扩展MainObj
,可以是任何内容。
我们还说我们有两个FirstObjSrc
和SecondObjSrc
对象都有getObj
方法。第一个返回FirstObj
,第二个返回SecondObj
。
这就是我在Purescript中实现的方式:
foreign import data ObjEff :: * -> !
foreign import data Obj :: *
foreign import data FirstObjSrc :: *
foreign import data SecondObjSrc :: *
foreign import somePropImpl :: forall a s e. a -> Eff (oe :: ObjEff s | e) Boolean
foreign import toggleSomePropImpl :: forall a s e. a -> Eff (oe :: ObjEff s | e) Unit
foreign import someOtherPropImpl :: ...
foreign import doSomethingWithOtherPropImpl :: ...
foreign import getStateImpl :: forall a b s e. (a -> Maybe a) -> Maybe a -> b -> Eff (oe :: ObjEff s | e) (Maybe s)
foreign import setStateImpl :: forall a s e. a -> s -> Eff (oe :: ObjEff s | e) Unit
foreign import getFirstObjImpl :: forall a s e. FirstObjSrc -> Eff (oe :: ObjEff s | e) a
foreign import getSecondObjImpl :: forall a s e. SecondObjSrc -> Eff (oe :: ObjEff s | e) a
class MainObj a where
someProp :: forall s e. a -> Eff (oe :: ObjEff s | e) Boolean
toggleSomeProp :: forall s e. a -> Eff (oe :: ObjEff s | e) Unit
class FirstObj a where
someOtherProp :: ...
doSomethingWithOtherProp :: ...
class (MainObj a) <= SecondObj a where
getState :: forall s e. a -> Eff (oe :: ObjEff s | e) (Maybe s)
setState :: forall s e. a -> s -> Eff (oe :: ObjEff s | e) Unit
class ObjSrc a where
getObj :: forall b s e. a -> Eff (oe :: ObjEff s | e) b
instance objIsMainObj :: MainObj Obj where
someProp = somePropImpl
toggleSomeProp = toggleSomePropImpl
instance objIsFirstObj :: FirstObj Obj where
someOtherProp = someOtherPropImpl
doSomethingWithOtherProp = doSomethingWithOtherPropImpl
instance objIsSecondObj :: SecondObj Obj where
getState = getStateImpl Just Nothing
setState = setStateImpl
instance firstObjSrcIsObjSrc :: ObjSrc FirstObjSrc where
getObj = getFirstObjImpl
instance secondObjSrcIsObjSrc :: ObjSrc SecondObjSrc where
getObj = getSecondObjImpl
foreign import getFirstObjSrc :: forall s e. Eff (oe :: ObjEff s | e) FirstObjSrc
foreign import getSecondObjSrc :: forall s e. Eff (oe :: ObjEff s | e) SecondObjSrc
所以,我对这段代码有一些疑问:
ObjEff
效果是否需要幻像类型s
?更新
让我们说上面的代码是某种虚构的浏览器(或NodeJS)API,所以没有办法以某种方式改变它。
答案 0 :(得分:0)
这个问题是基于比当前语言更旧且不兼容的版本。 Eff
和效果行已被删除,而其位置为Effect
(实际上,Eff
没有效果行)。我猜想*
已被Type
取代,!
已被删除(当我开始使用PureScript时,这些符号不存在)。
用于对象的符号有点混乱,因为它既不是JavaScript也不是我熟悉的任何其他标准符号。我的解释是,例如,
MainObj {
someProp: false
toggleSomeProp: function () {
if (this.someProp)
this.someProp = false
else
this.someProp = true
}
...
}
表示此含义(在JavaScript中)
function MainObj() {
}
MainObj.prototype.someProp = false;
MainObj.prototype.toggleSomeProp = function () {
if (this.someProp)
this.someProp = false
else
this.someProp = true
}
// ...
在这种情况下,PureScript中可能的定义是:
foreign import data MainObj ∷ Type
foreign import someProp ∷ MainObj → Effect Boolean
foreign import toggleSomeProp ∷ MainObj → Effect Unit
实施文件为:
exports.someProp = function (mainObj) {
return function () {
return mainObj.someProp;
};
};
exports.toggleSomeProp = function (mainObj) {
return function () {
return mainObj.toggleSomeProp();
};
}
或者为了更好的内联和更容易的实现,这:
foreign import data MainObj ∷ Type
foreign import someProp ∷ EffectFn1 MainObj Boolean
foreign import toggleSomeProp ∷ EffectFn1 MainObj Unit
实现将是:
exports.someProp = function (mainObj) {
return mainObj.someProp;
};
exports.toggleSomeProp = function (mainObj) {
return mainObj.toggleSomeProp();
}
有多种方法可以做到(而且已经完成),但这是我几乎唯一使用的方法,因为它简单,明了且具有高度的适应性。
someProp
必须有效导入,因为给定相同的对象它可以返回不同的结果。 toggleSomeProp
必须有效导入,因为它以可观察的方式(通过someProp
来改变状态)。