我有一个泛化到函数func
的函数,该函数将应用于MyDataType1
和另一个MyDataType1
这样的
setThis :: (Functor f0, Applicative f0) => Lens' MyDataType1 (f0 Float) -> Float -> MyDataType1 -> MyDataType1 -> MyDataType1
setThis func toThis dataType1 dataType2 = dataType2 & func %~ (\a -> (+) <$> a <*> delta
where baseStat = dataType1 ^. func -- baseStat has type Maybe Float
delta = (\a -> toThis * a) <$> baseStat -- also have type Maybe Float
其中MyDataType1
是(与print
一起使用。每个数值都是Float
)
data MyDataType1 = MyDataType1 { _name = Just "First"
, _length = Just 5.5
, _dmsTypes = Just
( DMS { _i = Just 1.9
, _j = Nothing
, _k = Just 95.9
}
)
}
函数setThis
赋予了默认记录功能,例如length
,常数Float
,用于从中获取基值的数据集和 a设置要修改的数据,请将_length
设置为一个数字,该数字是原始值与另一组值乘以某个常数之和。
它的作用与给定功能length
时一样。
我想做的是,在给定(dmsTypes . _j)
之类的功能时,其行为完全相同
setThis (dmsTypes . _Just . _j) 0.3 (someY) (someY) -- someY :: MyDataType1
尽管我只是这样做,GHC也会引发此错误
Could not deduce (Applicative f) arising from a use of ‘_Just’
from the context: Functor f
bound by a type expected by the context:
Lens' MyDataType1 (Maybe Float)
Possible fix:
add (Applicative f) to the context of
a type expected by the context:
Lens' MyDataType1 (Maybe Float)
GHC似乎完全知道我应该怎么做,但我不知道该怎么做。
答案 0 :(得分:2)
由于func
所指向的事物可能不存在,因此它应该是遍历(任意数量的聚焦值),而不是 lens (恰好是重点价值)。
setThis
中使用 setter 的部分(即(%~)
)保持不变,但 getter 部分(即{ {1}})应该改用 fold 和(^.)
。在这种情况下,(^?)
将具有两层dataType1 ^? func
,一层来自Maybe
,一层来自(^?)
(在当前的func
中),我可能想用f0
来弄平。
join
现在baseState = join (dataType1 ^? func)
必须是f0
。
Maybe