与Writer monad的函数组合?

时间:2017-02-08 10:39:39

标签: haskell function-composition 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"

为什么此计算错误与.而不是$?也许我对功能构成的理解不正确?

2 个答案:

答案 0 :(得分:4)

使用.的函数组合意味着生成的组合将接收参数。

这部分:

execWriter . myFunction 1 2

可以这样写得更明确:

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

由于myFunction只接受两个参数,因此会出现编译错误。

您是否在代码中使用了$,如下所示:

execWriter $ myFunction 1 2

扩展的结果代码等同于:

execWriter (myFunction 1 2)

哪个有效。

答案 1 :(得分:2)

除了Chad所说的,这是因为常规函数应用程序(不使用$)的优先级高于所有运算符(中缀函数),包括.

如果你这样写的话你的例子会有用:

(execWriter . myFunction 1) 2

相当于:

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

然后评估为:

execWriter (myFunction 1 2)