我正在研究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"
为什么此计算错误与.
而不是$
?也许我对功能构成的理解不正确?
答案 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)