1

ネストされたレコードのプロパティを更新するために purescript-lens を使用しようとしています。ただし、レンズを作成してプロパティを取得すると、次の型エラーが発生します。

Warning: Error at src/Main.purs line 150, column 38 - line 152, column 3: 
Error in declaration performAction
Cannot unify { description :: u24500 | u24501 } with Main.Item. Use --force to continue.

私はレンズとピュアスクリプトに比較的慣れていないので、おそらく単純で明白なものです。

このエラーを生成する関連コードは次のとおりです (はい、purescript-thermite-todomvc に基づいています)。

data Action
  = NewItem String String String String String
  | RemoveItem Index
  | SetEditText String
  | DoNothing

data Item = Item
            { description :: String
            , keywords :: String
            , link_title :: String
            , profile :: String
            , title :: String
            }

data State = State
  { item :: Item
  , editText :: String
  }

_State :: LensP State { item :: _, editText :: _ }
_State f (State st) = State <$> f st

item :: forall r. LensP { item :: _ | r } _
item f st = f st.item <#> \i -> st { item = i }

editText :: forall r. LensP { editText :: _ | r } _
editText f st = f st.editText <#> \i -> st { editText = i }

itemDescription :: forall r. LensP { description :: _ | r } _
itemDescription f it = f it.description <#> \d -> it { description = d }

performAction :: T.PerformAction _ Action (T.Action _ State)
performAction _ action = T.modifyState (updateState action)
  where
  updateState :: Action -> State -> State
  updateState (NewItem s1 _ _ _ _) = _State .. item .. itemDescription .~ s1
  updateState (SetEditText s)    = _State .. editText .~ s
  updateState DoNothing          = id

更新しようとしているプロパティは st.item.description で、上記のエラーは「updateState (NewItem...」で始まる行を参照しています。不思議なことに、次の行でも同じエラーが報告されています。

型エラーを解決する方法についてのアイデアはありますか?

ありがとう

4

1 に答える 1

0

レンズの種類をあまり一般的でないようにすることで、これを「修正」しました。また、Philが purescript-lens の「24 日間」レビューで使用した構文に基づいてレンズを作成しました。その構文はそれほど不透明ではありません。

item :: LensP State Item
item = lens (\(State st) -> st.item) (\(State st) item -> State (st { item = item }))

editText :: LensP State String
editText = lens (\(State st) -> st.editText) (\(State st) editText -> State (st { editText = editText }))

itemDescription :: LensP Item String
itemDescription = lens (\(Item it) -> it.description) (\(Item it) description -> Item (it { description = description }))

_State繰り返しますが、レンズの種類を単純にするために、次のレンズの使用を取り除きましたperformAction

performAction :: T.PerformAction _ Action (T.Action _ State)
performAction _ action = T.modifyState (updateState action)
  where
  updateState :: Action -> State -> State
  updateState (NewItem s1 _ _ _ _) = \st -> st # item..itemDescription.~ s1
  updateState (SetEditText s)    = \st -> st # editText.~ s
  updateState DoNothing          = id

もっとエレガントで一般的で完全な解決策があると確信していますが、purescript-lens をよりよく理解するまで待つ必要があります。

于 2015-01-13T12:12:53.560 に答える