Итак, скажем, я хочу определить новый тип, в котором находится функция:
newtype Test m a = Test(m -> (a, m))
Это может быть использовано для хранения состояния какого-либо рода.
Теперь допустим, что я хотел бы реализовать fmap для этого нового типа.
instance Functor (Test m) where
--fmap :: (a -> b) -> Test m a -> Test m a -> b
fmap f (Test f1) (Test f2) = ?
Поскольку функции нового типа не позволяют использовать сопоставление с образцом для разделения f1 и f2.
Например, я изначально думал, что, возможно, я мог бы передать входное значение f2 в вызов f1, чтобы получить (a, m) кортеж, но я не думаю, что вы можете сделать это.
т.е.
tup = f1 (get input of f2)
Кто-нибудь может предоставить мне, какие концепции мне не хватает, чтобы справиться с этим сценарием, или это просто невозможно?
Спасибо
ОБНОВЛЕНИЕ
Большое спасибо Реду и Виллему Ван Осему.
Похоже, мне не хватало понимания того, как использовать оператор композиции (.).
По сути, ключом здесь является использование (.), Чтобы получить первый элемент кортежа, а затем выполнить несколько частичных определений функций, чтобы перейти в состояние, необходимое для fmap. Вот моя реализация fmap без использования библиотечной функции. Целенаправленно, многословно, чтобы помочь с пониманием.
alterParamStateHelper :: (a -> b) -> (m -> a) -> m -> (b, m)
alterParamStateHelper f1 f2 m = (b, m)
where
a = f2 e
b = f1 a
alterParamState :: (a -> b) -> (m -> (a, m)) -> (m -> (b, m))
alterParamState f1 f2 = alterParamStateHelper f1 h1
where
h1 = fst . f2--m -> a
instance Functor (Test m) where
-- fmap :: (a -> b) -> Test m a -> Test m b
fmap f1 (Test f2) = Test (alterParamState f1 f2)