假设我有一个嵌套结构,如下所示:
data Bar = Bar { _id :: Integer, _bars :: [Bar] }
data Foo = Foo { _bars :: [Bar] }
我有Foo
一堆Bars
个id
个:
foo = Foo [Bar 1 [Bar 2], Bar 3 [Bar 4, Bar 5]]
如何,或许使用镜头,我修改foo
使Bar 5
成为Bar 6
?
我知道我使用fclabels
来做这样的事情:
mkLabel ''Foo
mkLabel ''Bar
modify bars (\bars -> ...) foo
但是栏可以无限嵌套。如何找到并修改具有指定ID的Bar
?
答案 0 :(得分:4)
是的,@property (nonatomic, retain) UITextField *activeTextField;
-(void)setActiveTextField:(UITextField *)activeTextField
{
_activeTextField = activeTextField;
}
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
self.activeTextField = textField;
}
-(void)textFieldDidEndEditing:(UITextField *)textField
{
self.activeTextField = nil;
}
-(void)keyboardWasShown:(NSNotification *)aNotification
{
if (self.activeTextField == nil)
{
return;
}
可以做到这一点。 Control.Lens.Plated
模块包含用于" Scrap Your Boilerplate" -style编程的工具,具有与lens
类似的自相似结构。这个想法很诱人:你解释了如何找到节点的直接子节点(通过编写Bar
),并且库递归地将遍历应用于整个结构。
Traversal' a a
(如果您不想自己实施{-# LANGUAGE TemplateHaskell #-}
import Control.Lens
data Bar = Bar { _lbl :: Int, _bars :: [Bar] } deriving (Show)
makeLenses ''Bar
instance Plated Bar where
plate = bars.traverse
,可以导出Data
并将plate
留空。)
transform :: Plated a => (a -> a) -> a -> a
采用修改单个节点并将其应用于整个结构的函数。
instance
使用您问题中的示例:
fiveToSix :: Bar -> Bar
fiveToSix = transform go
where go bar
| bar^.lbl == 5 = bar & lbl .~ 6
| otherwise = bar
另一个例子是,对于funzies,让我们使用cosmos
从ghci> let bars = [Bar 1 [Bar 2 []], Bar 3 [Bar 4 [], Bar 5 []]]
ghci> map fiveToSix bars
[Bar 1 [Bar 2 []], Bar 3 [Bar 4 [], Bar 6 []]]
中提取所有Bar 5
。
Bar