Написание cojoin или cobind для n-мерного типа сетки
Используя типичное определение натуралов уровня типа, я определил n-мерную сетку.
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeFamilies #-}
data Nat = Z | S Nat
data U (n :: Nat) x where
Point :: x -> U Z x
Dimension :: [U n x] -> U n x -> [U n x] -> U (S n) x
dmap :: (U n x -> U m r) -> U (S n) x -> U (S m) r
dmap f (Dimension ls mid rs) = Dimension (map f ls) (f mid) (map f rs)
instance Functor (U n) where
fmap f (Point x) = Point (f x)
fmap f d@Dimension{} = dmap (fmap f) d
Теперь я хочу сделать это экземпляром Comonad, но я не могу полностью обернуть его вокруг этого.
class Functor w => Comonad w where
(=>>) :: w a -> (w a -> b) -> w b
coreturn :: w a -> a
cojoin :: w a -> w (w a)
x =>> f = fmap f (cojoin x)
cojoin xx = xx =>> id
instance Comonad (U n) where
coreturn (Point x) = x
coreturn (Dimension _ mid _) = coreturn mid
-- cojoin :: U Z x -> U Z (U Z x)
cojoin (Point x) = Point (Point x)
-- cojoin ::U (S n) x -> U (S n) (U (S n) x)
cojoin d@Dimension{} = undefined
-- =>> :: U Z x -> (U Z x -> r) -> U Z r
p@Point{} =>> f = Point (f p)
-- =>> :: U (S n) x -> (U (S n) x -> r) -> U (S n) r
d@Dimension{} =>> f = undefined
С помощьюcojoin
на n-мерной сетке будет производиться n-мерная сетка из n-мерных сеток. Я хотел бы предоставить экземпляр с той же идеей, что иэтотчтостоимость изcojoined сетка в (x, y, z) должна бытьоригинал сеткасосредоточены на (х, у, z). Похоже, что для адаптации этого кода нам необходимоn
для того, чтобы выполнитьn
"fmaps" иn
«катится». Вы не должны делать это таким образом, но если это помогает, тогда вы идете.