Мы можем иметь полиморфную функцию f :: a -> b
, реализованную для разных пар a
и b
. Как мы можем сделатьHaskell: применять полиморфную функцию дважды
twice :: (a -> b) -> a -> c
twice f x = f (f x)
тип проверка? то есть как я могу написать функцию, которая применяет функцию polyorphic?
С Rank2Types
мы можем получить немного ближе, но не совсем там:
{-# LANGUAGE Rank2Types #-}
twice1 :: (forall a. a -> (m a)) -> b -> (m (m b))
twice1 f = f . f
twice2 :: (forall a. m a -> a) -> m (m b) -> b
twice2 f = f . f
так, то некоторые полиморфные функции могут быть применены два раза:
\> twice1 (:[]) 1
[[1]]
\> twice2 head [[1]]
1
Можем ли мы пойти дальше?
The question was asked over Haskell cafe10 лет назад, но на него не ответили (с классами типов это становится много шаблонов).
Is 'double :: Functor f => (forall a. F a -> g a) -> (forall a. F (f a) -> g (g a))' достаточно хорошо? 'дважды = дважды1' с' f ~ Identity' и 'дважды = дважды2' с' g ~ Identity'. Что-то вроде 'дважды (Id. Head). дважды (\ (Id a) -> [a]) 'например, работает. – user2407038