我正在研究J.Gibbons教授关于Haskell中类似APL编程的扩展摘要。我坚持Applicative
为超立方体数据类型定义实例,尽管论文指出它是完全可行的。简化示例如下。
{-# 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
-}
回想一下有关Applicative
实例的Vector n a
类型(例如,按其长度索引的列表类型)的知识,我试图将其pure
视为replicate
(给定值的n元复制)。但似乎这需要类型级别的大小写(例如pure a = case fs of '[] -> Scalar a; (f ': gs) -> <something using the fact that Applicative f>
),据我所知在Haskell中不可用。
您可以为Hyper '[]
和定义单独的实例Hyper (f ': fs)
(这是一种“类型级别的情况”。)
您无法定义一个Applicative (Hyper fs)
行为符合您期望的实例,因为它会违反参数性。当然,我可以isScalar :: Hyper fs -> Bool
用明显的方式来定义。那是什么isScalar (pure ())
?
(在这里,Applicative (Hyper fs)
由于f
在这种Hyper (f ': fs)
情况下需要约束,因此您将始终无法定义单个实例。)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句