如何对函数进行对比?
How to contramap over functions?
鉴于:
class Contravariant (f :: * -> *) where
contramap :: (a -> b) -> f b -> f a
以下代码被拒绝。我希望通过 String -> Int
上的对映 Int -> Bool
得到 String -> Bool
(谓词)。我觉得自己很愚蠢,因为我一定做出了一些错误的假设。请帮助我理解错误信息。为什么第二个参数与我认为需要的不同?
Prelude Control.Lens> contramap length (>0) "Hello"
<interactive>:25:19: error:
• Couldn't match type ‘Bool’ with ‘Int’
Expected type: [Char] -> Int
Actual type: [Char] -> Bool
• In the second argument of ‘contramap’, namely ‘(> 0)’
In the expression: contramap length (> 0) "Hello"
In an equation for ‘it’: it = contramap length (> 0) "Hello"
实际上,您正在寻找无聊的旧协变 Functor
实例。
> fmap (>0) length "Hello"
True
在更高层次上,您可能正在寻找 null
函数。对于许多类型,length
将遍历您传递给它的整个数据结构,而 null
通常不会。
这里还有对错误消息的简短解释。第一:
contramap length :: (Contravariant f, Foldable t) => f Int -> f (t a)
(>0) :: (Num a, Ord a) => (->) a Bool
我已经按照我希望的建议方式对事物进行了调整。为了将 contramap length
应用到 (>0)
,我们需要设置 f ~ (->) a
和 Int ~ Bool
。第二个显然是不可能的,所以编译器会抱怨。 (N.B。第一个等式只是有点不可能;即使你提供了一个返回 Int
的函数,你也会遇到问题,但编译器还没有注意到,因为第二个等式胜过它。即:(->) a
没有 Contravariant
实例,也不可能!)
逆变仅适用于类型构造函数的最后一个参数。您可能需要 Profunctor
,它表示类型构造函数在倒数第二个参数中是逆变的,在最后一个参数中是协变的(如常规 Functor)。
<Gurkenglas> > lmap length (>0) "hello"
<lambdabot> True
鉴于:
class Contravariant (f :: * -> *) where
contramap :: (a -> b) -> f b -> f a
以下代码被拒绝。我希望通过 String -> Int
上的对映 Int -> Bool
得到 String -> Bool
(谓词)。我觉得自己很愚蠢,因为我一定做出了一些错误的假设。请帮助我理解错误信息。为什么第二个参数与我认为需要的不同?
Prelude Control.Lens> contramap length (>0) "Hello"
<interactive>:25:19: error:
• Couldn't match type ‘Bool’ with ‘Int’
Expected type: [Char] -> Int
Actual type: [Char] -> Bool
• In the second argument of ‘contramap’, namely ‘(> 0)’
In the expression: contramap length (> 0) "Hello"
In an equation for ‘it’: it = contramap length (> 0) "Hello"
实际上,您正在寻找无聊的旧协变 Functor
实例。
> fmap (>0) length "Hello"
True
在更高层次上,您可能正在寻找 null
函数。对于许多类型,length
将遍历您传递给它的整个数据结构,而 null
通常不会。
这里还有对错误消息的简短解释。第一:
contramap length :: (Contravariant f, Foldable t) => f Int -> f (t a)
(>0) :: (Num a, Ord a) => (->) a Bool
我已经按照我希望的建议方式对事物进行了调整。为了将 contramap length
应用到 (>0)
,我们需要设置 f ~ (->) a
和 Int ~ Bool
。第二个显然是不可能的,所以编译器会抱怨。 (N.B。第一个等式只是有点不可能;即使你提供了一个返回 Int
的函数,你也会遇到问题,但编译器还没有注意到,因为第二个等式胜过它。即:(->) a
没有 Contravariant
实例,也不可能!)
逆变仅适用于类型构造函数的最后一个参数。您可能需要 Profunctor
,它表示类型构造函数在倒数第二个参数中是逆变的,在最后一个参数中是协变的(如常规 Functor)。
<Gurkenglas> > lmap length (>0) "hello"
<lambdabot> True