Есть ли лучший способ добавить значения двух пользовательских типов данных, где оба являются экземплярами MonoFunctor? - PullRequest
0 голосов
/ 12 января 2019

У меня есть некоторые данные, определенные как

{-# LANGUAGE RankNTypes      #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies    #-}

module Test where

import           Control.Lens
import           Data.MonoTraversable

data Custom = Custom { _a :: Maybe Float
                     , _b :: Maybe Float
                     }
makeLenses ''Custom


type instance Element Custom = Maybe Float

instance MonoFunctor Custom where
    omap f (Custom ja jb) = Custom (f ja) (f jb)

data MainI = MainI { _name   :: Maybe String
                   , _dTypes :: Maybe Custom
                   }
makeLenses ''MainI

У меня есть функция, определенная следующим образом

addEm :: MainI -> MainI -> MainI
addEm toGet toSet = toSet & dTypes %~ (\x -> emFunctions <$> x <*> baseTypes)
    where baseTypes =
             (toGet & (dTypes . _Just)  %~ (omap (\x -> pure (* 1.5) <*> x))) ^. dTypes 

, который просто принимает каждое значение внутри Custom, добавляет 1.5 раз значения в toGet к значениям в toSet.

Это делается с помощью этой вспомогательной функции

emFunctions :: Custom -> Custom -> Custom
emFunctions toGetC toSetC = toSetC
     & a %~ (\x -> (+) <$> x <*> toGetC ^. a)
     & b %~ (\x -> (+) <$> x <*> toGetC ^. b)

Так что мне было интересно, есть ли лучший способ сделать это?

Особенно это делать без вспомогательной функции.


Также связанный вопрос: можно ли суммировать данные Custom? Например, если _a == 5.5 и _b == 5.0, функция sumCustom вернет 10.5

...