Applicative example for hypercuboid

I work through Professor J. Gibbons' extended essay on APL-like programming in Haskell. I stuck to the definition of an instance Applicativefor a hypercube-like data type, although the document says that it is perfectly doable. A simplified example as follows .

{-# LANGUAGE KindSignatures, GADTs, TypeFamilies, TypeOperators, MultiParamTypeClasses, DataKinds #-}

import Control.Applicative
import Data.Traversable (Traversable)

class (Applicative f, Traversable f) => Dim f

class Shapely (fs :: [* -> *])
instance Shapely '[]
instance (Dim f, Shapely fs) => Shapely (f ': fs)

-------------------------------------
--            Hypercuboid datatype
-------------------------------------
data Hyper :: [* -> *] -> * -> * where
    Scalar :: a -> Hyper '[] a
    Prism  :: (Dim f, Shapely fs) => 
                Hyper fs (f a) -> Hyper (f ': fs) a

instance Functor (Hyper fs) where
    fmap f (Scalar a) = Scalar $ f a
    fmap f (Prism p)  = Prism $ fmap (fmap f) p

instance Applicative (Hyper fs) where
    pure a = undefined 
{- `pure a = Scalar a` gives:
            Couldn't match type ‘fs’ with ‘'[]’
                  ‘fs’ is a rigid type variable bound by
                       the instance declaration
            Expected type: Hyper fs a
              Actual type: Hyper '[] a
-}

Recall what is known about the instance Applicativefor the type Vector n a(for example, indexed by its length according to the list) I tried to think about purehow replicate(n-ary replication of the given value), But it seems that this requires a font type (for example, pure a = case fs of '[] -> Scalar a; (f ': gs) -> <something using the fact that Applicative f>) which, as far as I known not available in Haskell.

+4
2

Hyper '[] Hyper (f ': fs) ( " ".)

Applicative (Hyper fs), , , . , isScalar :: Hyper fs -> Bool ; isScalar (pure ())?

( Applicative (Hyper fs) , f Hyper (f ': fs).)

+6

case, , . :

data Shapely (fs :: [* -> *]) where
    ShZ :: Shapely '[]
    ShS :: (Dim f) => Shapely fs -> Shapely (f ': fs)

, :

class SShapely (fs :: [* -> *]) where
    shapely :: Shapely fs

instance SShapely '[] where
    shapely = ShZ

instance (Dim f, SShapely fs) => SShapely (f ': fs) where
    shapely = ShS shapely

, , , . -

pureSh :: Shapely fs -> a -> Hyper fs a
pureSh  ShZ    x = Scalar x
pureSh (ShS s) x = Prism (pureSh s (pure x))

instance SShapely fs => Applicative (Hyper fs) where
    pure = pureSh shapely

ShZ , fs ~ '[], fs '[] Scalar x . ShS .

check, Prism SShapely fs, Shapely fs (, , ), :

data Shapely (fs :: [* -> *]) where
    ShZ :: Shapely '[]
    ShS :: (Dim f, SShapely fs) => Shapely (f ': fs)

class SShapely (fs :: [* -> *]) where
    shapely :: Shapely fs

instance SShapely '[] where
    shapely = ShZ

instance (Dim f, SShapely fs) => SShapely (f ': fs) where
    shapely = ShS

pureSh :: Shapely fs -> a -> Hyper fs a
pureSh ShZ x = Scalar x
pureSh ShS x = Prism (pureSh shapely (pure x))

instance SShapely fs => Applicative (Hyper fs) where
    pure = pureSh shapely

ShS Shapely Shapely fs , SShapely fs, a Shapely fs. .

.

+1

Source: https://habr.com/ru/post/1650841/


All Articles