Возможно ли это монадное / аппликативное упрощение?

Это возможно?, (есть >>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
Другие вопросы по тегам