Обучение тому, как использовать контркарту, когда ожидается (a -> возможно b) вместо (a -> b) в качестве первого параметра (Haskell) - PullRequest
1 голос
/ 13 октября 2019

Я изучаю Haskell, и меня попросили выполнить это упражнение:

Реализация нового типа данных с именем NovoPred, который должен иметь конструктор значений с тем же именем. Также в нем должно быть поле с именем runNovoPred с типом Maybe a -> Bool. Затем создайте экземпляр Contravariant Functor для типа 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 функциявозвращается. Поэтому сделать x . y невозможно, поскольку x ожидает получить значение, не совпадающее с тем, что на самом деле возвращает y.

Итак, я думаю, мне нужен способ сделатьФункция y возвращает значение типа Maybe b. К сожалению, я понятия не имею, как это сделать, поскольку contramap ожидает получить что-то вроде a -> b в качестве первого параметра вместо чего-то вроде a -> Maybe b (это то, что мне нужно). Не могли бы вы помочь мне с этим?

1 Ответ

5 голосов
/ 13 октября 2019

Если у вас есть функция y :: a -> b и вам нужно преобразовать Maybe a в Maybe b, вы можете просто fmap сверх Maybe:

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