无法将类型“a”与“a1”匹配
Couldn't match type `a` with `a1`
我正在做 Haskell Programming from First Principles, Chapter 16 中的练习。问题是要求我们为数据类型编写 Functor 定义:
{-# LANGUAGE FlexibleInstances #-}
newtype Flip f a b = Flip (f b a) deriving (Eq, Show)
newtype K a b = K a
instance Functor (Flip K a) where
fmap = undefined
这是我的尝试:
{-# LANGUAGE FlexibleInstances #-}
newtype Flip f a b =
Flip (f b a)
deriving (Eq, Show)
newtype K a b =
K a
-- instance Functor (K a) where
-- fmap _ (K a) = K a
instance Functor (Flip K a) where
fmap _ (Flip (K a)) = Flip (K a)
但无法编译:
chapEx2.hs:17:25: error:
• Couldn't match type ‘a1’ with ‘b’
‘a1’ is a rigid type variable bound by
the type signature for:
fmap :: forall a1 b. (a1 -> b) -> Flip K a a1 -> Flip K a b
at chapEx2.hs:17:3-6
‘b’ is a rigid type variable bound by
the type signature for:
fmap :: forall a1 b. (a1 -> b) -> Flip K a a1 -> Flip K a b
at chapEx2.hs:17:3-6
Expected type: Flip K a b
Actual type: Flip K a a1
• In the expression: Flip (K a)
In an equation for ‘fmap’: fmap f (Flip (K a)) = Flip (K a)
In the instance declaration for ‘Functor (Flip K a)’
• Relevant bindings include
a :: a1 (bound at chapEx2.hs:17:19)
f :: a1 -> b (bound at chapEx2.hs:17:8)
fmap :: (a1 -> b) -> Flip K a a1 -> Flip K a b
(bound at chapEx2.hs:17:3)
|
17 | fmap f (Flip (K a)) = Flip (K a)
| ^^^^^^^^^^
有人可以解释错误消息吗?我只是对错误信息感到困惑:
- 为什么编译器将
Actual type
推断为 Flip K a a1
而不是 Flip K a b
?
- 为什么编译器还要去匹配
K
的第三个参数呢?类型K
的定义只有一个a
,没有b
,b
只出现在数据类声明的左边(=
的左边符号)而不是 newtype K a b = K a
. 的类型类声明(=
符号的右侧)
- 为什么
Flip (K a)
不能改成Flip x
?
- 我发现
fmap f (Flip (K a)) = Flip (K (f a))
可以编译,有什么区别?
问题 1
你犯了一个错误。 Flip
意味着您需要映射 first 参数 K
:
instance Functor (Flip K a) where
fmap f (Flip (K a)) = Flip (K (f a))
问题 2
这是有充分理由的。其中之一是给类型一个 phantom 参数可能非常有用(维护程序不变量或指导实例解析)。如果编译器忽略它们,这些技术将毫无价值。 (注意:您可以在需要时忽略它们,并且 Data.Coerce
提供了一些这样做的高级工具。您可能还没有准备好进行强制转换)。
另一个原因是,要弄清楚哪些类型与其他类型相等要困难得多,因为您必须查看每种类型的详细信息。可能还有更多原因。
旁白
FlexibleInstances
在这里显得相当尴尬和局限。这是我的做法:
-- A functor in the second to last type argument
class Functor2 p where
fmap2 :: (a -> a') -> p a b -> p a' b
instance Functor2 K where
fmap2 = -- you fill in the blank
instance Functor2 p => Functor (Flip p b) where
fmap = -- you fill in the blank
我正在做 Haskell Programming from First Principles, Chapter 16 中的练习。问题是要求我们为数据类型编写 Functor 定义:
{-# LANGUAGE FlexibleInstances #-}
newtype Flip f a b = Flip (f b a) deriving (Eq, Show)
newtype K a b = K a
instance Functor (Flip K a) where
fmap = undefined
这是我的尝试:
{-# LANGUAGE FlexibleInstances #-}
newtype Flip f a b =
Flip (f b a)
deriving (Eq, Show)
newtype K a b =
K a
-- instance Functor (K a) where
-- fmap _ (K a) = K a
instance Functor (Flip K a) where
fmap _ (Flip (K a)) = Flip (K a)
但无法编译:
chapEx2.hs:17:25: error:
• Couldn't match type ‘a1’ with ‘b’
‘a1’ is a rigid type variable bound by
the type signature for:
fmap :: forall a1 b. (a1 -> b) -> Flip K a a1 -> Flip K a b
at chapEx2.hs:17:3-6
‘b’ is a rigid type variable bound by
the type signature for:
fmap :: forall a1 b. (a1 -> b) -> Flip K a a1 -> Flip K a b
at chapEx2.hs:17:3-6
Expected type: Flip K a b
Actual type: Flip K a a1
• In the expression: Flip (K a)
In an equation for ‘fmap’: fmap f (Flip (K a)) = Flip (K a)
In the instance declaration for ‘Functor (Flip K a)’
• Relevant bindings include
a :: a1 (bound at chapEx2.hs:17:19)
f :: a1 -> b (bound at chapEx2.hs:17:8)
fmap :: (a1 -> b) -> Flip K a a1 -> Flip K a b
(bound at chapEx2.hs:17:3)
|
17 | fmap f (Flip (K a)) = Flip (K a)
| ^^^^^^^^^^
有人可以解释错误消息吗?我只是对错误信息感到困惑:
- 为什么编译器将
Actual type
推断为Flip K a a1
而不是Flip K a b
? - 为什么编译器还要去匹配
K
的第三个参数呢?类型K
的定义只有一个a
,没有b
,b
只出现在数据类声明的左边(=
的左边符号)而不是newtype K a b = K a
. 的类型类声明( - 为什么
Flip (K a)
不能改成Flip x
? - 我发现
fmap f (Flip (K a)) = Flip (K (f a))
可以编译,有什么区别?
=
符号的右侧)
问题 1
你犯了一个错误。 Flip
意味着您需要映射 first 参数 K
:
instance Functor (Flip K a) where
fmap f (Flip (K a)) = Flip (K (f a))
问题 2
这是有充分理由的。其中之一是给类型一个 phantom 参数可能非常有用(维护程序不变量或指导实例解析)。如果编译器忽略它们,这些技术将毫无价值。 (注意:您可以在需要时忽略它们,并且 Data.Coerce
提供了一些这样做的高级工具。您可能还没有准备好进行强制转换)。
另一个原因是,要弄清楚哪些类型与其他类型相等要困难得多,因为您必须查看每种类型的详细信息。可能还有更多原因。
旁白
FlexibleInstances
在这里显得相当尴尬和局限。这是我的做法:
-- A functor in the second to last type argument
class Functor2 p where
fmap2 :: (a -> a') -> p a b -> p a' b
instance Functor2 K where
fmap2 = -- you fill in the blank
instance Functor2 p => Functor (Flip p b) where
fmap = -- you fill in the blank