Возможно ли это монадное / аппликативное упрощение? - PullRequest
1 голос
/ 07 февраля 2012

Возможно ли это ?, (есть функция >>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 ]

8 голосов
/ 07 февраля 2012

Если вы сначала написали insertTransaction, возможно, имеет смысл изменить его на

insertTransaction :: Int -> Int -> Day -> MyReaderT Bool
insertTransaction amount price day = ....

Тогда вы могли бы сказать

logTransaction :: Int -> Int -> MyReaderT Bool
logTransaction amount price = currentDay >>= insertTransaction amount price
6 голосов
/ 07 февраля 2012

Это на самом деле невозможно без хитрости класса типов, потому что вы пытаетесь «поднять» функцию с произвольным числом аргументов - что, конечно, не совсем хорошо определенное понятие в 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
...