Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 哈斯凯尔的纯和记忆有什么区别?_Haskell_Applicative_Monoids - Fatal编程技术网

Haskell 哈斯凯尔的纯和记忆有什么区别?

Haskell 哈斯凯尔的纯和记忆有什么区别?,haskell,applicative,monoids,Haskell,Applicative,Monoids,在学校里,我的任务是写一个函数,如果数字是偶数,它会在列表的左边追加数字。类型签名为: appendIfEven :: (Applicative f, Monoid (f a), Integral a) => a -> f a -> f a 我的答案是下面的代码 appendIfEven :: (Applicative f, Monoid (f a), Integral a) => a -> f a -> f a appendIfEven x ms = if

在学校里,我的任务是写一个函数,如果数字是偶数,它会在列表的左边追加数字。类型签名为:

appendIfEven :: (Applicative f, Monoid (f a), Integral a) => a -> f a -> f a
我的答案是下面的代码

appendIfEven :: (Applicative f, Monoid (f a), Integral a) => a -> f a -> f a
appendIfEven x ms = if x `mod` 2 == 0 then mempty x `mappend` ms else ms
Haskell可以编译我的代码,但它不能正常工作。经过一些实验后,我将mempty切换到pure:

这很有效。但是为什么呢?pure==mempty不应该吗?(在这方面)
这对我的导师来说似乎并不重要。然而,我真的想更多地了解Haskell以及我错在哪里……

考虑将此应用于列表

mempty == []

pure 5 = [5]
那些看起来和我不太像。尤其是,
memptyx
应该是输入错误的


基本上,
mempty
给了你一个空的东西,而
pure x
给了你一个里面有
x
的东西。

你无意中使用了一个意外的monoid,这让你的代码得以编译

编写
mempty x`mappend`ms
时,
ms
值的类型为
fa
,它是一个幺半群。这迫使
mempty x
具有相同的类型,因为
mappend
需要两个相同类型的参数。因此,我们必须

mempty x :: f a
这意味着,由于
x::a

mempty :: a -> f a
奇怪吧

嗯,碰巧在库中有一个实例

instance Monoid t => Monoid (u -> t) where
   mempty = \_ -> mempty
   ...
您无意中使用了将
x
传递到
mempty
,因为在上面的实例中
t
可以是
fa
,而
u
可以是
a
。Haskell解析了monoid约束,因此使用了这个实例

这也意味着

mempty x `mappend` ms

(\_ -> mempty) x `mappend` ms  -- this is the mempty for (f a), instead!
mempty `mappend` ms   -- this is the mempty for (f a), instead!
ms
这和

(\_ -> mempty) x `mappend` ms  -- this is the mempty for (f a), instead!
mempty `mappend` ms   -- this is the mempty for (f a), instead!
ms
这和

(\_ -> mempty) x `mappend` ms  -- this is the mempty for (f a), instead!
mempty `mappend` ms   -- this is the mempty for (f a), instead!
ms
因此,您的代码完全忽略
x
参数


相比之下,
pure x
在一般情况下依赖于
x
,因此最终结果可能会非常不同。

例如,它们有不同的类型。如果它们有不同的类型,它们怎么可能是相同的东西呢?它之所以编译是因为
a->b
有一个
Monoid
实例,只要
b
也是一个
Monoid
,在这种情况下
mempty=const mempty
@user253751
a->b
有一个
Monoid实例,在这种情况下,
mempty
本身也是一个函数。
mempty
是为
monoidb=>a->b
定义为
const mempty
@chepner是的,我有一种感觉,编译器不会抱怨,因为一个合适的实例确实存在,或者理论上可以使其存在。仍然不能使它成为一个合理的表达式(除非您真的在使用这样的实例)。在适当的上下文中,将
mempty
用作函数是有意义的。相反,在我看来,在
mempty x
中立即应用它是没有意义的,因为它与
mempty
是等价的(在相同的上下文中)。函数实例使著名的技巧
比较snd和比较fst
,与
(fg)xy=(fxgx)y=fxyxy
成为可能。