Haskell 用编写器monad编写函数?

Haskell 用编写器monad编写函数?,haskell,function-composition,writer-monad,Haskell,Function Composition,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 :: Write

我正在研究
编剧
单子,我有以下几点:

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))
execWriter $ myFunction 1 2
(execWriter . myFunction 1) 2
由于
myFunction
只接受两个参数,因此会出现编译错误

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

(\x -> execWriter (myFunction 1 2 x))
execWriter $ myFunction 1 2
(execWriter . myFunction 1) 2
扩展后的代码相当于:

execWriter (myFunction 1 2)

这是有效的。

函数与
组合意味着生成的组合将接收一个参数

这部分:

execWriter . myFunction 1 2
可以这样更明确地编写:

(\x -> execWriter (myFunction 1 2 x))
execWriter $ myFunction 1 2
(execWriter . myFunction 1) 2
由于
myFunction
只接受两个参数,因此会出现编译错误

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

(\x -> execWriter (myFunction 1 2 x))
execWriter $ myFunction 1 2
(execWriter . myFunction 1) 2
扩展后的代码相当于:

execWriter (myFunction 1 2)

这是有效的。

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

如果您是这样写的,那么您的示例就会起作用:

(\x -> execWriter (myFunction 1 2 x))
execWriter $ myFunction 1 2
(execWriter . myFunction 1) 2
这相当于:

(\x -> execWriter (myFunction 1 x)) 2
其计算结果如下:

execWriter (myFunction 1 2)

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

如果您是这样写的,那么您的示例就会起作用:

(\x -> execWriter (myFunction 1 2 x))
execWriter $ myFunction 1 2
(execWriter . myFunction 1) 2
这相当于:

(\x -> execWriter (myFunction 1 x)) 2
其计算结果如下:

execWriter (myFunction 1 2)
好的,
(::(b->c)->(a->b)->a->c
操作符需要两个函数,每个函数都有一个参数,右边的
myFunction
这里没有
execWriter
需要的参数(或者至少没有)。您还可以定义
(.:)=()。()
然后使用,
execWriter.:myFunction$12
。它也被称为“猫头鹰操作员”。(
(.:)
已经在
数据中定义。Composition
-)那么
(.:(b->c)->(a->b)->a->c
操作符需要两个函数,每个函数都有一个参数,右边的
myFunction
这里没有
execWriter
需要的参数(或者至少没有该参数)。您还可以定义
(.:)=(.(.:)
然后使用,
execWriter.:myFunction$1 2
。它也被称为“owl运算符”。(
(.:)
已在
Data.Composition
-中定义)