3

3 つのオブジェクトがあるとします。

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します。状態プロパティ (および get/set メソッド) で拡張され、何でもかまいません。MainObjSecondObjMainObj

また、2 つのオブジェクトがFirstObjSrcありSecondObjSrc、どちらにもgetObjメソッドがあるとします。最初の 1 つは返さFirstObjれ、2 番目の 1 つは返されます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

したがって、このコードについていくつか質問があります。

  1. この実装は正しいですか?
  2. ObjEff効果はファントムタイプが必要sですか?
  3. そうであれば(またはそうでない場合)、その理由を理解したいと思います(https://wiki.haskell.org/Phantom_typeと他のいくつかの説明を読みましたが、基本を理解していると思います。しかし、効果は私を少し混乱させます)。

アップデート

上記のコードは架空のブラウザー (または NodeJS) API の一種であり、何らかの形で変更する方法はないとしましょう。

4

1 に答える 1

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

于 2019-04-05T00:57:55.463 に答える