我尝试了解Haskell类型级编程。我写了一个小函数来在类型级别列表中查找一个键,一个符号:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
import GHC.TypeLits
type family Lookup (x :: k) (l :: [(k,v)]) :: k where
Lookup k ('(k,a) ': ls) = a
Lookup k ('(x,a) ': ls) = Lookup k ls
Lookup k '[] = TypeError (Text "Key not found: ")
GHC(8.0.1)编译此函数时没有错误 现在我需要测试GHCi中的功能。在GHCi中,我设置了选项:
:set -XDataKinds
:set -XTypeOperators
并尝试运行第一个测试示例:
:kind! Lookup "bar" '[("foo", Int), ("bar", String)]
The Strings" bar"和" foo"应该是Type-level Strings aka Symbols
。
GHC拒绝了我的小测试用例:
<interactive>:1:14: error:
• Expected kind ‘[(Symbol, v0)]’,
but ‘'[("foo", Int), ("bar", String)]’ has kind ‘[*]’
• In the second argument of ‘Lookup’, namely
‘'[("foo", Int), ("bar", String)]’
In the type ‘Lookup "bar" '[("foo", Int), ("bar", String)]’
问题是如何更改测试示例,因此GHC将接受它。
注意:我的类型级别函数Lookup
位于其第一个版本中,可能是错误的,也许我应该使用CmpSymbol
或进行其他更改。但是,这个SO问题的主题不。
答案 0 :(得分:4)
(k1, k2)
是类型/种类k1
和k2
的元素对类型,'(a, b)
是类型级对(请注意'
})。
'(a, b) :: (k1, k2) with a :: k1 and b :: k2
修正:
Lookup "bar" '[ '("foo", Int), '("bar", String)]