这个Monad/Applicative Simplfication可能吗?

Zhe*_*hen 1 monads haskell

有可能吗?(有一个>>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
Run Code Online (Sandbox Code Playgroud)

对此:

logTransaction :: Int -> Int -> MyReaderT Bool
logTransaction = currentDay `>>magic` insertTransaction
Run Code Online (Sandbox Code Playgroud)

我认为应该有一个运营商,>>magic但我找不到它.也不<*><$>.

dav*_*420 8

如果你insertTransaction在第一时间写作,那么重构它可能是有意义的

insertTransaction :: Int -> Int -> Day -> MyReaderT Bool
insertTransaction amount price day = ....
Run Code Online (Sandbox Code Playgroud)

然后你可以说

logTransaction :: Int -> Int -> MyReaderT Bool
logTransaction amount price = currentDay >>= insertTransaction amount price
Run Code Online (Sandbox Code Playgroud)


ehi*_*ird 6

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

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

logTransaction :: Int -> Int -> MyReaderT Bool
logTransaction amount price = join $ insertTransaction
    <$> currentDay
    <*> pure amount
    <*> pure price
Run Code Online (Sandbox Code Playgroud)

我认为这可能很好 - 提议的运算符似乎很难读给我看,因为很难说有多少参数正在处理或者它们在哪里.

使用Strathclyde Haskell Enhancement预处理器,logTransaction可以使用成语括号编写如下:

logTransaction :: Int -> Int -> MyReaderT Bool
logTransaction amount price = (| insertTransaction currentDay ~amount ~price @ |)
Run Code Online (Sandbox Code Playgroud)

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

logTransaction :: Int -> Int -> MyReaderT Bool
logTransaction = ((currentDay >>=) .) . flip . flip insertTransaction
Run Code Online (Sandbox Code Playgroud)