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

时间:2019-01-09 14:11:29

标签: haskell types applicative lens

我有一个泛化到函数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似乎完全知道我应该怎么做,但我不知道该怎么做。

1 个答案:

答案 0 :(得分:2)

由于func所指向的事物可能不存在,因此它应该是遍历(任意数量的聚焦值),而不是 lens (恰好是重点价值)。

setThis中使用 setter 的部分(即(%~))保持不变,但 getter 部分(即{ {1}})应该改用 fold (^.)。在这种情况下,(^?)将具有两层dataType1 ^? func,一层来自Maybe,一层来自(^?)(在当前的func中),我可能想用f0来弄平。

join

现在baseState = join (dataType1 ^? func) 必须是f0

Maybe