Haskell 如何编写map/fmap模拟(a->;b)->;F m a->;F m b
大家好! 我有以下类型:Haskell 如何编写map/fmap模拟(a->;b)->;F m a->;F m b,haskell,Haskell,大家好! 我有以下类型: data FixItem m a = KeepItem|SkipItem|FixItem (m (a -> a)) fixItem f = FixItem $ pure f 我想写函数mapFix::(a->b)->fixitemma->fixitemmb。当我尝试时: mapFix f SkipItem = SkipItem -- good mapFix f KeepItem = fixItem f -- error "rigid type"!!! mapFi
data FixItem m a = KeepItem|SkipItem|FixItem (m (a -> a))
fixItem f = FixItem $ pure f
我想写函数mapFix::(a->b)->fixitemma->fixitemmb
。当我尝试时:
mapFix f SkipItem = SkipItem -- good
mapFix f KeepItem = fixItem f -- error "rigid type"!!!
mapFix f (FixItem mf) = FixItem $ pure (.) <*> (pure f) <*> mf -- too!
如何为此类类型编写mapFix或实现Functor实例(FixItem将
a
修复为a
,而不是b
,即修复是a->a
,而不是a->b
)?您不能为您的数据类型实现Functor
类型类。是因为
a->a
在一个构造函数中。当你有功能时,你应该更加小心。但简而言之,类型变量a
处于逆变位置,因此无法对该类型变量实现Functor
尽管您可以为您的数据类型实现。因为a
处于协变和逆变位置,所以您的数据类型是不变函子
可以帮助您:
您不能为您的数据类型实现
Functor
类型类。是因为
a->a
在一个构造函数中。当你有功能时,你应该更加小心。但简而言之,类型变量a
处于逆变位置,因此无法对该类型变量实现Functor
尽管您可以为您的数据类型实现。因为a
处于协变和逆变位置,所以您的数据类型是不变函子
可以帮助您:
我怀疑函子是不可能的,那么这是否意味着
mapFix
函数也是不可能的呢?顺便说一句,当我将类型更改为FixItem ma b=FixItem(m(a->b))| SkipItem | KeepItem
并尝试实现Functor时,我再次遇到了关于正确类型“a”的错误…嗯,我得到了:FixItem中纯f
和mf
的组合隐藏a->b
,而FixItem只支持a->a
。所以,mapFix是不可能的。但是有可能实现fixitemm a b=FixITem(m(a->b))|…
Functor实例吗?啊,好的,完成:)fmap f(FixITem mf)=FixITem$pure()(pure f)mf
。谢谢@是的,函子在理论上是不可能的。这意味着mapFix
功能也不可能实现:(如果您将a->a
更改为a->b
并具有类型FixItem ma b
,则可以编写mapFix
,当给定b->c
函数时,该函数可以将FixItem ma b
映射到FixItem ma c
,因为b
类型变量处于协变位置。我怀疑函子是冒充的。)ble,那么这是否意味着mapFix
功能也不可能实现?顺便说一句,当我将类型更改为FixItem m a b=FixItem(m(a->b))时|SkipItem | KeepItem
并尝试实现Functor,我再次得到关于正确类型“a”的错误…嗯,我得到了:组合纯f
和mf
在FixITem中隐藏a->b
,而FixITem只支持a->a
。因此,mapFix是不可能的。但是有可能实现FixITem m=FixITem(m)吗(a->b);…
函子实例?啊,好的,完成:)fmap f(FixItem mf)=FixItem$pure()(pure f)mf
。谢谢!@Paul AG是的,函子在某种理论意义上是不可能的。这意味着mapFix
函数也是不可能的:(如果您将a->a
更改为a->b
,并且具有类型fixab
,则可以编写mapFix
,当给定b->c
函数时,该函数可以将fixab
映射到fixac
,因为b
类型变量处于协变位置。
• Couldn't match type ‘b’ with ‘a’
‘b’ is a rigid type variable bound by
the type signature for:
mapFix :: forall (m :: * -> *) a b.
Applicative m =>
(a -> b) -> FixItem m a -> FixItem m b
at src/test.hs:235:11
‘a’ is a rigid type variable bound by
the type signature for:
mapFix :: forall (m :: * -> *) a b.
Applicative m =>
(a -> b) -> FixItem m a -> FixItem m b
at src/test.hs:235:11
Expected type: b -> b
Actual type: a -> b
• In the first argument of ‘fixItem’, namely ‘f’
In the expression: fixItem f
In an equation for ‘mapFix’: mapFix f KeepItem = fixItem f
• Relevant bindings include
f :: a -> b (bound at src/test.hs:236:8)
mapFix :: (a -> b) -> FixItem m a -> FixItem m b
(bound at src/test.hs:236:1)