haskell - 封闭类型族中的种类多态性
问题描述
我试图Ty
从计算. Atom
我首先尝试使用一个封闭的类型族,就像论文所做的那样:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
module GenericK where
import Data.Kind
type Kind = Type
-- | TyVar represents type parameters that the data takes
data TyVar (zeta :: Kind) (k :: Kind) :: Type where
VZ :: TyVar (x -> xs) x
VS :: TyVar xs k -> TyVar (x -> xs) k
-- | Atom is similar to K1
data Atom (zeta :: Kind) (k :: Kind) :: Type where
Var :: TyVar zeta k -> Atom zeta k
Kon :: k -> Atom zeta k
(:@:) :: Atom zeta (l -> k) -> Atom zeta l -> Atom zeta k
--| Gamma is a context
data Gamma (zeta :: Kind) where
Eta :: Gamma Type
(:&:) :: k -> Gamma ks -> Gamma (k -> ks)
type family Ty zeta (alpha :: Gamma zeta) (t :: Atom zeta k) :: k where
Ty (k -> ks) (t :&: alpha) (Var VZ) = t
Ty (k -> ks) (t :&: alpha) (Var (VS v)) = Ty ks alpha (Var v)
Ty zeta alpha (Kon t) = t
Ty zeta alpha (f :@: x) = (Ty zeta alpha f) (Ty zeta alpha x)
然而,GHC 抱怨道:
• Expected kind ‘Atom zeta k’,
but ‘f’ has kind ‘Atom zeta (k -> k)’
• In the third argument of ‘Ty’, namely ‘f’
In the type ‘(Ty zeta alpha f) (Ty zeta alpha x)’
In the type family declaration for ‘Ty’
该错误消息对我来说没有多大意义,因为显然f
应该有 kindAtom zeta (l -> k)
并且x
应该有 kind Atom zeta l
。
所以我尝试使用一个开放类型的系列并且它起作用了:
type family Ty zeta (alpha :: Gamma zeta) (t :: Atom zeta k) :: k
type instance Ty (k -> ks) (t :&: alpha) (Var VZ) = t
type instance Ty (k -> ks) (t :&: alpha) (Var (VS v)) = Ty ks alpha (Var v)
type instance Ty zeta alpha (Kon t) = t
type instance Ty zeta alpha (f :@: x) = (Ty zeta alpha f) (Ty zeta alpha x)
我很好奇为什么封闭式家庭不起作用。我想这可能与种类多态性有关,但我真的不知道种类检查在 GHC 中是如何工作的。
解决方案
推荐阅读
- c - C 中的 snprintf() 不单独处理目标字符串的最低两个字节
- .net-core - 在哪里可以找到 IPluralizer?
- python - 对复合 sqlalchemy 查询的顺序有任何性能影响吗?
- laravel - 从 Laravel Blade 动态页面标题中删除空格
- python - Python 将更改持久保存到函数的参数中而不返回(leetcode:“不返回任何内容,而是就地修改根”)
- python - Python循环中的正则表达式
- javascript - 单击路由器链接时强制重新渲染 vue 组件
- rss - Google 搜索新闻标签的 RSS 提要
- kubernetes - kubectl logs 命令似乎不尊重 --limit-bytes 选项
- go - 如何在 Go 中将整数转换为字节