我试图使Twice成为应用程序的成员,但在functor实现中得到“'a'的冲突定义”:另外,我不确定如何正确实现<*>:// >
Traverse[Either[A, ?]]
答案 0 :(得分:6)
我猜这些错误比语法上更具语法性。在您的定义中:
location.href = <endpoint>/authorize
与Twice f f <*> Twice x x = Twice ((f x) (f x))
定义相同:
Functor
您在开头写了两个fmap f (Twice a a) = Twice (f a) (f a)
和两个f
。 Haskell不允许这样做(Prolog允许,但是即使那样也可能不是您的意思)。
此外,您在正文中写道:
x
这意味着您将使用((f x) (f x))
函数和f x
参数进行函数调用,这又可能不是您想要的。
我们可以在语法上将其修复为:
f x
请注意,您仍然需要通过考虑为这些类型类记录的约束来证明这是有效的instance Functor Twice where
fmap f (Twice a b) = Twice (f a) (f b)
instance Applicative Twice where
pure x = Twice x x
Twice f g <*> Twice x y = Twice (f x) (g y)
和Functor
实例。
答案 1 :(得分:2)
这里是问题及其纠正:
instance Functor Twice where
-- fmap f (Twice a a) = Twice (f a) (f a)
-- ^^^ you define `a` twice here. Replace this with:
fmap f (Twice a b) = Twice (f a) (f b)
instance Applicative Twice where
pure x = Twice x x -- You don't need brackets here so I removed them.
-- Twice f f <*> Twice x x = Twice ((f x) (f x))
-- ^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^^^^^
-- You define f and x twice.
-- You are also misusing brackets - this is not how to apply functions.
-- A corrected version:
Twice f1 f2 <*> Twice x1 x2 = Twice (f1 x1) (f2 x2)
首先,如果您不给单独的参数单独的名称,则此将会导致错误。想象我写f a a = a + 6
,然后要求您评估f 1 2
。
第二,您误解了Haskell函数的应用方式。让我澄清一下:在大多数语言中,您写f(a,b,c)
,但是在Haskell中,您写f a b c
。如果您写f (a b c)
,则读为f(a(b,c))
。
答案 2 :(得分:0)
混淆源于对数据和类型使用相同的名称;除新手Haskellers以外的所有人都可以接受的通用且推荐的做法。
现在,您可以使用其他名称,以减轻学习和习惯Haskell数据类型声明时的认知负担:
data Twice a = MkTwice a a deriving (Show) -- 'Mk' is for "make"
-- Twice a -- a type
-- MkTwice :: a -> a -> Twice a -- data constructor
instance Functor Twice where
-- fmap (f :: a -> b) :: Twice a -> Twice b
fmap f (MkTwice x y) = MkTwice (f x) (f y) -- transform both fields
instance Applicative Twice where
pure x = MkTwice x x -- create two fields from one value
MkTwice f g <*> MkTwice x y = MkTwice (f x) (g y) -- combine both fields
Twice a
是类型,而a
是类型变量。
MkTwice
是此类型的数据构造函数。它从两个类型Twice a
的值(例如a
和x :: a
)中生成类型y :: a
的值。值大约出现在Haskell定义中=
的右侧。
它也用在模式中,用于类型Twice a
的值。模式显示在Haskell定义中=
的左侧。 Haskell的模式中不能有 no 个重复的模式变量。每个模式变量代表一些值。
每个类型变量代表一种类型。
我敢打赌,如果为类型和数据构造函数使用不同的名称,您不会犯这些错误。