【问题标题】:Is this Monad/Applicative Simplfication possible?这个 Monad/Applicative Simplification 可能吗?
【发布时间】:2012-02-06 20:05:19
【问题描述】:

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

我认为应该有一个像&gt;&gt;magic 这样的运算符,但我找不到。也不是&lt;*&gt; 也不是&lt;$&gt;。

【问题讨论】:

    标签: haskell monads


    【解决方案1】:

    如果你一开始就写了insertTransaction,那么重构它可能是有意义的

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

    那你可以说

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

    【讨论】:

      【解决方案2】:

      如果没有 typeclass 技巧,这实际上是不可能的,因为你试图用任意数量的参数“提升”一个函数——当然,由于柯里化,这在 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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-02-06
        • 1970-01-01
        • 1970-01-01
        • 2016-04-28
        • 1970-01-01
        • 1970-01-01
        • 2012-11-12
        • 2016-04-22
        相关资源
        最近更新 更多