Haskell 对应用程序(->;)的混淆
假定Haskell 对应用程序(->;)的混淆,haskell,Haskell,假定Applicative(->)实现为: instance Applicative ((->) a) where pure = const (<*>) f g x = f x (g x) 基于这种理解,将成为: -- f x (g x) (pure (+)) x ((Just 3) x) 但这不起作用,因为(仅3)不接受任何参数。所以我显然没有意识到什么,尽管我不确定那是什么 我对这种情况是如何发生的感到困惑: Prelude> :t pure (+
Applicative(->)
实现为:
instance Applicative ((->) a) where
pure = const
(<*>) f g x = f x (g x)
基于这种理解,
将成为:
-- f x (g x)
(pure (+)) x ((Just 3) x)
但这不起作用,因为(仅3)
不接受任何参数。所以我显然没有意识到什么,尽管我不确定那是什么
我对这种情况是如何发生的感到困惑:
Prelude> :t pure (+) <*> Just 3
pure (+) <*> Just 3 :: Num a => Maybe (a -> a)
前奏曲>:t纯(+)仅3
纯(+)仅3::Num a=>可能(a->a)
请解释一下它是如何工作的。根据我对事物的理解,手动执行这些步骤,我无法达到与
ghci
相同的结果,因为
的右侧参数仅为3
,因此使用的应用程序实例必须是Maybe的实例,而不是函数的实例。因此,左侧也必须是a,因此pure(+)==Just(+)
。现在您可以看到
如何组合这些:它打开两个Just
构造函数,应用函数,并将结果放回Just
:这与Just(+)3)
或Just(3+)
相同。正如您在ghci中所看到的,这两个对象具有相同的类型。由于
的右侧参数仅为3,因此所使用的应用程序实例必须是Maybe的实例,而不是函数的实例。因此,左侧也必须是a,因此pure(+)==Just(+)
。现在您可以看到
如何组合这些:它打开两个Just
构造函数,应用函数,并将结果放回Just
:这与Just(+)3)
或Just(3+)
相同。正如您在ghci中所看到的,这两个东西具有相同的类型。此示例演示了Applicationive的Maybe实例,而不是(>)a
实例。此示例演示了Applicationive的Maybe实例,而不是(>)a
实例。太棒了!这是我遗漏的一部分,这个应用程序可能就是正在应用的那个。作为将来的参考,我怎么知道是右侧决定了类实例?这有没有记录在案?双方都决定了:他们必须是相同的。我在描述类型推断器(GHCI的,还有你头脑中的那个)发现正在使用哪个实例的过程。
的类型是Applicative f=>f(a->b)->f a->f b
,并且所有三个f
都必须相同。由于右侧在f~可能
处明显“锁定”,因此可以推断左侧(和返回类型)也必须具有f~可能
,这就是你如何发现哪个pure
和
起作用的原因。@kurzweil4不要忘记,如果x::a
那么pure x
对于任何f
应用程序都是f a
类型。在您的例子中,a
已经涉及到一个应用程序((>)b
),但这与此无关。相比之下,(+)…
强制
处理(>)b
应用程序,因为这是左侧的内容;但是,pure(+)…
不强制任何特定的应用程序,并且将适应右侧的任何应用程序。太棒了!这是我遗漏的一部分,这个应用程序可能就是正在应用的那个。作为将来的参考,我怎么知道是右侧决定了类实例?这有没有记录在案?双方都决定了:他们必须是相同的。我在描述类型推断器(GHCI的,还有你头脑中的那个)发现正在使用哪个实例的过程。
的类型是Applicative f=>f(a->b)->f a->f b
,并且所有三个f
都必须相同。由于右侧在f~可能
处明显“锁定”,因此可以推断左侧(和返回类型)也必须具有f~可能
,这就是你如何发现哪个pure
和
起作用的原因。@kurzweil4不要忘记,如果x::a
那么pure x
对于任何f
应用程序都是f a
类型。在您的例子中,a
已经涉及到一个应用程序((>)b
),但这与此无关。相比之下,(+)…
强制
处理(>)b
应用程序,因为这是左侧的内容;但是,pure(+)…
不强制任何特定的应用程序,它将适应右侧的任何应用程序。
-- f x (g x)
(pure (+)) x ((Just 3) x)
Prelude> :t pure (+) <*> Just 3
pure (+) <*> Just 3 :: Num a => Maybe (a -> a)