Изучение того, как использовать contramap, когда ожидается (a - ›Возможно b) вместо (a -› b) в качестве первого параметра (Haskell)

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

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


person chrometic    schedule 12.10.2019    source источник
comment
В NovoPred (x . something) something не только должен возвращать Maybe a, но также получает Maybe b. Как теперь построить такую ​​функцию из y :: b -> a?   -  person Bergi    schedule 13.10.2019


Ответы (1)


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

contramap y (NovoPred x) = NovoPred (x . fmap y)
person Fyodor Soikin    schedule 12.10.2019