简体   繁体   English

这种Monad /应用简化可能吗?

[英]Is this Monad/Applicative Simplfication possible?

Is it possible?, (there is a >>magic function) to simplify this: 有可能吗?,(有>>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

To this: 对此:

logTransaction :: Int -> Int -> MyReaderT Bool
logTransaction = currentDay `>>magic` insertTransaction

I think there should be one operator like >>magic but I can't found it. 我认为应该有一个像>>magic这样的运算符,但我找不到它。 Nor <*> neither <$> . 也不<*>都不<$>

If you wrote insertTransaction in the first place, it might make sense to refactor it to 如果您首先编写insertTransaction ,则将其重构为

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

Then you could say 那你可以说

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

This isn't really possible without typeclass trickery, because you're trying to "lift" a function with an arbitrary number of arguments — which is, of course, not really a well-defined concept in Haskell, due to currying. 没有类型类技巧,这实际上是不可能的,因为您试图“提升”具有任意数量参数的函数-当然,由于curry,这在Haskell中并不是一个明确定义的概念。

The best you're likely to get in standard, readable Haskell is this: 在标准的可读性Haskell中,您可能会得到的最好的结果是:

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

I think this is probably fine — the proposed operator seems quite difficult to read to me, since it's hard to tell how many arguments are being processed or where they're going. 我认为这可能很好–建议的运算符对我来说似乎很难读,因为很难确定正在处理多少个参数或它们要去往何处。

With the Strathclyde Haskell Enhancement preprocessor, logTransaction could be written as follows, using idiom brackets : 使用Strathclyde Haskell增强预处理器,可以使用成语括号logTransaction编写如下:

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

Finally, it is technically possible to write logTransaction in a point-free style, but I wouldn't recommend it: 最后,从技术上讲,可以采用无点样式编写logTransaction ,但我不建议这样做:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM