学习如何在预期 (a -> Maybe b) 而不是 (a -> b) 作为第一个参数 (Haskell) 时使用 contramap

Learning how to use contramap when is expected (a -> Maybe b) instead of (a -> b) as the first parameter (Haskell)

我正在学习Haskell,我被要求解决这个问题:

Implement a new data type named NovoPred that should have a value constructor with the same name. Also it should have a field named runNovoPred with type Maybe a -> Bool Then, create an Functor Contravariant instance for type NovoPred

为了解决这个练习,我做了这个解决方案:

module Oitavo where

import           Data.Functor.Contravariant

newtype NovoPred a =
  NovoPred
    { runNovoPred :: Maybe a -> Bool
    }

instance Contravariant NovoPred where
    contramap y (NovoPred x) = NovoPred (x . y)

您可能已经注意到,此解决方案根本不起作用。 Contramap 需要有这样的结构:(a -> b) -> f b -> f a,问题是 x 函数期望接收一个看起来像 Maybe b 的值,而它实际上接收的是一个值 b 因为那是 y 函数 returns。因此,不可能执行 x . y,因为 x 期望收到的值与 y 实际上 return 不匹配。

所以,我想我需要一种方法使 y 函数 return 成为 Maybe b 类型的值。不幸的是,我不知道如何去做,因为 contramap 期望收到像 a -> b 这样的东西作为第一个参数,而不是像 a -> Maybe b 这样的东西(这就是我需要的)。你能帮我一下吗?

如果你有一个函数 y :: a -> b 并且你需要将 Maybe a 转换为 Maybe b,你可以 fmap over Maybe:

contramap y (NovoPred x) = NovoPred (x . fmap y)