与 Writer monad 的函数组合?

Function composition with the Writer monad?

我正在研究 Writer monad 并且具有以下内容:

myFunction :: Int -> Int -> Writer String Int
myFunction e1 e2 
   | e1 > e2 = do
      tell ("E1 greater")
      return (e1)
   | otherwise = do
      tell ("E2 greater")
      return (e2)

main = do
-- execWriter :: Writer w a -> w 
   print $ execWriter . myFunction 1 2 

错误:

"Couldn't match type ‘WriterT String Data.Functor.Identity.Identity Int’with ‘a0 -> Writer c0 a1’
  Expected type: a0 -> Writer c0 a1
    Actual type: Writer String Int"

为什么这个计算错误是 . 而不是 $?也许我对函数组合的理解不正确?

具有 . 的函数组合意味着生成的组合将接收一个参数。

这部分:

execWriter . myFunction 1 2

可以更明确地写成这样:

(\x -> execWriter (myFunction 1 2 x))

因为 myFunction 只需要两个参数,你会得到一个编译错误。

您是否在代码中使用了 $,例如:

execWriter $ myFunction 1 2

扩展后的代码等同于:

execWriter (myFunction 1 2)

哪个有效。

除了 Chad 所说的之外,发生这种情况是因为常规函数应用程序(不使用 $)比所有运算符(中缀函数)具有更高的优先级,包括 ..

如果您这样写,您的示例会有效:

(execWriter . myFunction 1) 2

相当于:

(\x -> execWriter (myFunction 1 x)) 2

然后计算为:

execWriter (myFunction 1 2)