这个Monad / Applicative Simplfication可能吗?

时间:2012-02-06 20:05:20

标签: haskell monads

有可能吗?(有一个>>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 个答案:

答案 0 :(得分:8)

如果你首先写了insertTransaction,那么重构它可能是有意义的

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

然后你可以说

logTransaction :: Int -> Int -> MyReaderT Bool
logTransaction amount price = currentDay >>= insertTransaction amount price

答案 1 :(得分:6)

如果没有类型类技巧,这是不可能的,因为你试图用任意数量的参数“提升”一个函数 - 当然,由于currying,这在Haskell中并不是一个明确定义的概念

你可能在标准的,可读的Haskell中得到的最好的是:

logTransaction :: Int -> Int -> MyReaderT Bool
logTransaction amount price = join $ insertTransaction
    <$> currentDay
    <*> pure amount
    <*> pure price

我认为这可能很好 - 提议的算子似乎很难读给我看,因为很难说出正在处理的论点数量或者它们的去向。

使用Strathclyde Haskell Enhancement预处理器,logTransaction可以使用idiom brackets编写如下:

logTransaction :: Int -> Int -> MyReaderT Bool
logTransaction amount price = (| insertTransaction currentDay ~amount ~price @ |)

最后,技术上可以用无点样式编写logTransaction,但我不推荐它:

logTransaction :: Int -> Int -> MyReaderT Bool
logTransaction = ((currentDay >>=) .) . flip . flip insertTransaction