purescript-镜头组合类型错误
purescript-lens composition type error
我正在尝试使用 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.
我对 lenses 和 purescript 比较陌生,所以这可能是一些简单明了的东西。
产生该错误的相关代码如下(是的,它基于 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..."的行,奇怪的是,下一行也报同样的错误.
关于如何解决类型错误的任何想法?
谢谢
我 "fixed" 通过降低镜头类型的通用性来做到这一点。我还根据 Phil 在他的 "24 days" review of purescript-lens 中使用的语法来构建镜头。我发现该语法不那么不透明。
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 }))
同样,为了保持镜头类型简单,我在 performAction
:
中去掉了 _State
镜头的使用
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 之后。
我正在尝试使用 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.
我对 lenses 和 purescript 比较陌生,所以这可能是一些简单明了的东西。
产生该错误的相关代码如下(是的,它基于 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..."的行,奇怪的是,下一行也报同样的错误.
关于如何解决类型错误的任何想法?
谢谢
我 "fixed" 通过降低镜头类型的通用性来做到这一点。我还根据 Phil 在他的 "24 days" review of purescript-lens 中使用的语法来构建镜头。我发现该语法不那么不透明。
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 }))
同样,为了保持镜头类型简单,我在 performAction
:
_State
镜头的使用
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 之后。