Очень интригующе.Это не совсем ответ, просто мысли ...
Так что нам нужна абстракция над (,)
и (->)
, которая предлагает обобщение assoc
/ curry
и first
/precompose
.Я обращусь к первым:
class Isotropic f where
lefty :: f a (f b c) -> f (a,b) c
righty :: f (a,b) c -> f a (f b c)
-- lefty ≡ righty⁻¹
instance Isotropic (,) where
lefty (a,(b,c)) = ((a,b),c)
righty ((a,b),c) = (a,(b,c))
instance Isotropic (->) where
lefty = uncurry
righty = curry
Легко.Вопрос в том, есть ли другие примеры этого?Конечно, есть тривиальный
newtype Biconst c a b = Biconst c
instance Isotropic (Biconst c) where
lefty (Biconst c) = Biconst c
righty (Biconst c) = Biconst c
Тогда получившийся в результате обличитель
class Profunctor p => Stubborn p where
stubborn :: p a b -> p (Biconst d c a) (Biconst d c b)
можно было бы также написать
class Profunctor p => Stubborn p where
stubborn :: p a b -> p d d
Но примеры этого, кажется, выходятскорее, слишком тривиально, чтобы быть пригодным для использования:
instance Stubborn (->) where
stubborn _ = id
instance (Monad m) => Stubborn (Kleisli m) where
stubborn (Kleisli _) = Kleisli pure
instance (Monoid m) => Stubborn (Forget m) where
stubborn (Forget _) = Forget $ const mempty
Я подозреваю, что (,)
и (->)
действительно являются единственными полезными случаями для этого, потому что они являются «свободным бифунктором» / «свободным»профюнктор »соответственно.