如何将应用上下文添加到 Lens 的 MyDataType 预期的类型?

How do I add an Applicative context to a type expected by Lens' MyDataType?

我有一个函数在函数 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一个数据集,从获取基值要修改的数据集,将_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 似乎完全知道我应该做什么,但我不知道该怎么做。

由于 func 指向的东西可能不存在,它应该是 遍历(任意数量的聚焦值)而不是 镜头(恰好是一个聚焦值)。

setThis 中使用 setter(即 (%~))的部分保持不变,但 getter 部分(即 (^.))应该使用 fold(^?)。在那种情况下,dataType1 ^? func 将有两层 Maybe,一层来自 (^?),一层来自 func(目前是 f0),你我可能想用 join.

压平
baseState = join (dataType1 ^? func)

现在 f0 必须是 Maybe

setThis :: Traversal' MyDataType1 (Maybe Float) -> ...