Возможно ли это монадное / аппликативное упрощение?
Это возможно?, (есть >>magic
функция), чтобы упростить это:
insertTransaction :: Day -> Int -> Int -> MyReaderT Bool
insertTransaction day amount price = ....
logTransaction :: Int -> Int -> MyReaderT Bool
logTransaction amount price = do
day <- currentDay
insertTransaction day amount price
К этому:
logTransaction :: Int -> Int -> MyReaderT Bool
logTransaction = currentDay `>>magic` insertTransaction
Я думаю, что должен быть один оператор, как >>magic
но я не могу его найти. ни <*>
ни <$>
,
2 ответа
Это на самом деле невозможно без хитрости класса типов, потому что вы пытаетесь "поднять" функцию с произвольным числом аргументов - что, конечно, не совсем хорошо определенное понятие в Haskell из-за каррирования.
Лучшее, что вы можете получить в стандартном, читабельном Haskell, это:
logTransaction :: Int -> Int -> MyReaderT Bool
logTransaction amount price = join $ insertTransaction
<$> currentDay
<*> pure amount
<*> pure price
Я думаю, что это, вероятно, хорошо - предложенный оператор кажется мне довольно сложным для чтения, поскольку трудно сказать, сколько аргументов обрабатывается или куда они идут.
С препроцессором Strathclyde Haskell Enhancement, logTransaction
можно написать следующим образом, используя идиоматические скобки:
logTransaction :: Int -> Int -> MyReaderT Bool
logTransaction amount price = (| insertTransaction currentDay ~amount ~price @ |)
Наконец, технически возможно написать logTransaction
в стиле без очков, но я бы не советовал:
logTransaction :: Int -> Int -> MyReaderT Bool
logTransaction = ((currentDay >>=) .) . flip . flip insertTransaction
Если вы написали insertTransaction
во-первых, возможно, имеет смысл изменить его
insertTransaction :: Int -> Int -> Day -> MyReaderT Bool
insertTransaction amount price day = ....
Тогда вы могли бы сказать,
logTransaction :: Int -> Int -> MyReaderT Bool
logTransaction amount price = currentDay >>= insertTransaction amount price