如何为常量 a b = 常量 a 实现可折叠实例?
How do I implement a foldable instance for Constant a b = Constant a?
我想为
实现可折叠
data Constant a b = Constant a
这是我直接的尝试:
instance Foldable (Constant a) where
foldr f b (Constant a) = f a b
我想了解的编译错误部分是:
Couldn't match expected type ‘a1’ with actual type ‘a’
‘a1’ is a rigid type variable bound by the type signature for
foldr :: (a1 -> b -> b) -> b -> Constant a a1 -> b
如您所见,折叠函数从我无权访问的常量中获取 "phantom type" (?) a1
;我只能访问 a
.
我该如何解决这个问题?请解释一下你的解决方案,因为我很困惑。
整个编译错误为:
try2/chap20/ex1.hs:9:30: Couldn't match expected type ‘a1’ with actual type ‘a’ …
‘a’ is a rigid type variable bound by
the instance declaration
at /Users/moron/code/haskell/book/try2/chap20/ex1.hs:8:10
‘a1’ is a rigid type variable bound by
the type signature for
foldr :: (a1 -> b -> b) -> b -> Constant a a1 -> b
at /Users/moron/code/haskell/book/try2/chap20/ex1.hs:9:3
Relevant bindings include
a :: a
(bound at /Users/moron/code/haskell/book/try2/chap20/ex1.hs:9:23)
f :: a1 -> b -> b
(bound at /Users/moron/code/haskell/book/try2/chap20/ex1.hs:9:9)
foldr :: (a1 -> b -> b) -> b -> Constant a a1 -> b
(bound at /Users/moron/code/haskell/book/try2/chap20/ex1.hs:9:3)
In the first argument of ‘f’, namely ‘a’
In the expression: f a b
Compilation failed.
我认为唯一的可能是:
data Constant a b = C a
-- foldMap :: Monoid m => (b -> m) -> t b -> m
instance Foldable (Constant a) where
foldMap f (C a) = mempty
这是简单的解决方案。
看看为什么你可以为这个定义这样做可能是有益的:
data Constant' a b = C' b
-- foldMap :: Monoid m => (b -> m) -> t b -> m
instance Foldable (Constant' a) where
foldMap f (C' a) = f a
这里t
是Constant' a
,所以
- 类型
t b
是 Constant' a b
。对于类型 b
. 的某些值 bval
,此类型的值具有结构 C bval
f
具有类型 b -> m
,因此我们可以将 f
应用于 bval
但是,在另一种情况下,我们没有 b
的值可应用于 f
,因此我们能做的最好的是 return mempty
.
Constant a b
不包含任何 b
-s,因此我们将其折叠起来,就好像它是 b
-s:
的空列表一样
instance Foldable (Constant a) where
foldr f z (Constant a) = z
Constant a b
中的 a
与 Foldable
实例无关,因为它只涉及最后一个参数。因此,您不能真正在定义中使用 a
。
我想为
实现可折叠data Constant a b = Constant a
这是我直接的尝试:
instance Foldable (Constant a) where
foldr f b (Constant a) = f a b
我想了解的编译错误部分是:
Couldn't match expected type ‘a1’ with actual type ‘a’
‘a1’ is a rigid type variable bound by the type signature for
foldr :: (a1 -> b -> b) -> b -> Constant a a1 -> b
如您所见,折叠函数从我无权访问的常量中获取 "phantom type" (?) a1
;我只能访问 a
.
我该如何解决这个问题?请解释一下你的解决方案,因为我很困惑。
整个编译错误为:
try2/chap20/ex1.hs:9:30: Couldn't match expected type ‘a1’ with actual type ‘a’ …
‘a’ is a rigid type variable bound by
the instance declaration
at /Users/moron/code/haskell/book/try2/chap20/ex1.hs:8:10
‘a1’ is a rigid type variable bound by
the type signature for
foldr :: (a1 -> b -> b) -> b -> Constant a a1 -> b
at /Users/moron/code/haskell/book/try2/chap20/ex1.hs:9:3
Relevant bindings include
a :: a
(bound at /Users/moron/code/haskell/book/try2/chap20/ex1.hs:9:23)
f :: a1 -> b -> b
(bound at /Users/moron/code/haskell/book/try2/chap20/ex1.hs:9:9)
foldr :: (a1 -> b -> b) -> b -> Constant a a1 -> b
(bound at /Users/moron/code/haskell/book/try2/chap20/ex1.hs:9:3)
In the first argument of ‘f’, namely ‘a’
In the expression: f a b
Compilation failed.
我认为唯一的可能是:
data Constant a b = C a
-- foldMap :: Monoid m => (b -> m) -> t b -> m
instance Foldable (Constant a) where
foldMap f (C a) = mempty
这是简单的解决方案。
看看为什么你可以为这个定义这样做可能是有益的:
data Constant' a b = C' b
-- foldMap :: Monoid m => (b -> m) -> t b -> m
instance Foldable (Constant' a) where
foldMap f (C' a) = f a
这里t
是Constant' a
,所以
- 类型
t b
是Constant' a b
。对于类型b
. 的某些值 f
具有类型b -> m
,因此我们可以将f
应用于bval
bval
,此类型的值具有结构 C bval
但是,在另一种情况下,我们没有 b
的值可应用于 f
,因此我们能做的最好的是 return mempty
.
Constant a b
不包含任何 b
-s,因此我们将其折叠起来,就好像它是 b
-s:
instance Foldable (Constant a) where
foldr f z (Constant a) = z
Constant a b
中的 a
与 Foldable
实例无关,因为它只涉及最后一个参数。因此,您不能真正在定义中使用 a
。