Haskell相当于C++模板而不是非类型
Haskell equivalent to C++ template over non-types
我的一般理解是,Haskell类型类与C++模板有一些概念上的相似之处 - 即你可以定义在类型上参数化的函数或类型。但是,C++模板的一个有用功能是您还可以使用非类型模板参数。例如,维基百科有一个很好的例子,说明如何创建编译时阶乘。
理想情况下,我想在哈斯克尔做同样的事情......我几乎可以使用DataKinds
扩展。以一个向量的典型示例为例,该向量将其长度编码为其类型(取自此处)。
data Nat = Ze | Su Nat
data Vec :: * -> Nat -> * where
Nil :: Vec a Ze
Cons :: a -> Vec a n -> Vec a (Su n)
我希望能够将向量的类型级"Nat"降级"回值级别(可能带有 ScopedTypeVariables
),以便我可以使用它,因为可以使用C++非类型模板参数作为常量值。全康。TypeLits 在 KnownNat
类中通过一些黑客来做到这一点(它为每个具体的文字伪造实例),但我显然不能自己在 Haskell 中编写这个。
感觉我想要的是不可能的,但我想对为什么它可能是不可能的有一些直觉。
我觉得依赖类型潜伏着...
执行此操作的技术称为单例类型(该链接还链接到库以支持此类型)。
核心思想是创建一个参数化类型构造函数,以便类型值和类型参数之间存在一对一的对应关系。 这是从上面链接中引用的第一篇论文中摘取的简化示例。
data SBool (a :: Bool) where
STrue :: SBool 'True
SFalse :: SBool 'False
现在只有一个类型SBool 'True
的值,即 STrue
。 我们还通过 GADT 魔法知道,当我们在SBool a
上进行模式匹配并得到STrue
时,a ~ 'True
. 现在,回到值,我们使用常规机制根据类型选择值:类型类。
class FromSBool (a :: 'Bool) where
fromSBool :: SBool a -> Bool
instance FromSBool 'True where
fromSBool STrue = True
instance FromSBool 'False where
fromSBool SFalse = False
这是一个非常简单的例子,但图书馆引用的论文涉及更多详细信息,或者你可以只使用库。 你是对的,类型级别的自然有点神奇。 相关的库是反射包,它允许您将值推入类型并在以后取回。
如果你对一些理论感兴趣,你可能也对论文Hasochism感兴趣。
- ArduinoJson 6.15.2:JsonObject没有命名类型
- 防止主数据类型C++的隐式转换
- 为什么 std::optional::operator=(U&&) 要求你是非标量类型?
- 是否可以在C++中有一个"generic"模板参数,该参数可以是非类型模板参数或类型?
- 为什么带有指针子对象的文字类类型的 constexpr 表达式不能是非类型模板参数
- 错误:请求成员 .. 是非类类型"char"
- 请求成员 'begin' in 'c' 中,它是非类类型 'char [101]' sort(c.begin(), c
- 为什么类的赋值运算符的返回类型通常是非常量(而不是常量)引用?
- 请求成员“写入”中的“chol_out_data”,这是非类类型
- C 要求成员''in'',该请求是非类型的“”
- 非分解功能类型可以是非类型参数
- C++:成员'的错误请求;Foo'在'f',其是非类类型'Foo*'
- 结构是非文本类型
- 请求以"y"表示的成员'print',这是非类类型
- Haskell相当于C++模板而不是非类型
- char* 具有内部链接,因此它不能不是非类型模板参数
- 请求会员是非类类型
- 错误:请求成员…在. .它是非类类型的
- 在c++中,可迭代类型应该是非多态的
- 错误:请求成员' end ' ..它是非类类型' double '