Часто у вас есть что-то вроде Applicative
без pure
или что-то вроде Monad
, но без return
. Пакет полугрупоид охватывает эти случаи с Apply
и Bind
. Сейчас я нахожусь в аналогичной ситуации, касающейся Arrow
, где я не могу определить значимую arr
функцию, но я думаю, что другие функции имели бы смысл.
Я определил тип, который содержит функцию, и это обратная функция:
import Control.Category
data Rev a b = Rev (a -> b) (b -> a)
reverse (Rev f g) = Rev g f
apply (Rev f _) x = f x
applyReverse (Rev _ g) y = g y
compose (Rev f f') (Rev g g') = Rev ((Prelude..) f g) ((Prelude..) g' f')
instance Category Rev where
id = Rev Prelude.id Prelude.id
(.) x y = compose x y
Теперь я не могу реализовать Arrow
, но что-то более слабое:
--"Ow" is an "Arrow" without "arr"
class Category a => Ow a where
first :: a b c -> a (b,d) (c,d)
first f = stars f Control.Category.id
second :: a b c -> a (d,b) (d,c)
second f = stars Control.Category.id f
--same as (***)
stars :: a b c -> a b' c' -> a (b,b') (c,c')
...
import Control.Arrow
instance Ow Rev where
stars (Rev f f') (Rev g g') = Rev (f *** g) (f' *** g')
Я думаю, что не могу реализовать эквивалент &&&
, так как он определен как f &&& g = arr (\b -> (b,b)) >>> f *** g
, а (\b -> (b,b))
необратим. Тем не менее, вы думаете, этот класс более слабого типа может быть полезным? Имеет ли это смысл с теоретической точки зрения?