Написание 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 «катится». Вы не должны делать это таким образом, но если это помогает, тогда вы идете.

Ответы на вопрос(3)

Ваш ответ на вопрос