0

我正在研究Writer单子并具有以下内容:

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"

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

4

2 回答 2

4

函数组合.意味着结果组合将接收一个参数。

这部分:

execWriter . myFunction 1 2

可以更明确地写成这样:

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

由于myFunction只需要两个参数,因此您会收到编译错误。

如果你$在你的代码中使用过,像这样:

execWriter $ myFunction 1 2

扩展后的代码等价于:

execWriter (myFunction 1 2)

这是有效的。

于 2017-02-08T10:49:27.863 回答
2

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

如果你这样写,你的例子就会奏效:

(execWriter . myFunction 1) 2

这相当于:

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

然后评估为:

execWriter (myFunction 1 2)
于 2017-02-08T10:53:50.480 回答