1

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

实现一个名为 NovoPred 的新数据类型,它应该有一个同名的值构造函数。它还应该有一个名为 runNovoPred 的字段,类型为 Maybe a -> Bool 然后,为 NovoPred 类型创建一个 Functor 逆变实例

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

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函数返回的。因此,这是不可能的x . y,因为期望收到一个与实际返回x的值不匹配的值。y

所以,我想我需要一种方法让y函数返回一个 type 的值Maybe b。不幸的是,我不知道如何做到这一点,因为contramap期望收到类似a -> b第一个参数的东西而不是类似的东西a -> Maybe b(这就是我需要的)。你能帮我解决这个问题吗?

4

1 回答 1

5

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

contramap y (NovoPred x) = NovoPred (x . fmap y)
于 2019-10-12T23:28:35.397 回答