作为思想实验的一部分, 我正在尝试强制执行以下属性 对于与类型TC相关联的类型族T 在哈斯克尔:
val
)具有以下功能:
有什么想法吗?
我最接近编译的是以下内容。它满足Property 1和Feature 1 但违反了财产2。
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
import GHC.TypeLits
-- Works, violates Property 2
class TC (l :: Symbol) where
data T l :: * -> *
label :: T l v -> String
val :: T l v -> v
instance TC "age" where
data T "age" v = T___age v
label x = "age"
val (T___age x) = x
-- The return type of val is determined by how one constructs T___age,
-- rather than implied by the "age" label.
foo = T___age 1 -- In GHCi, foo :: Num v => T "age" v
bar = T___age "1" -- and bar :: T "age" [Char]
有没有办法在实例声明中指定val的返回类型
与T___age相关联而不是数据构建时?我试过以下,
但它与Int
构造函数中的T___age
与从val返回的v
不匹配。
class TC (l :: Symbol) where
data T l :: *
label :: T l -> String
val :: T l -> v
instance TC "age" where
data T "age" = T___age Int
label x = "age"
val (T___age x) = x
错误:
Couldn't match expected type ‘v’ with actual type ‘Int’
‘v’ is a rigid type variable bound by
the type signature for val :: T "age" -> v at src/Basics.hs:108:3
Relevant bindings include
val :: T "age" -> v (bound at src/Basics.hs:108:3)
In the expression: x :: Int
In an equation for ‘val’: val (T___age x) = x :: Int
In the instance declaration for ‘TC "age"
感谢您提供任何帮助。
答案 0 :(得分:3)
我不完全确定我明白你想要什么,但也许这个?
class TC (l :: Symbol) where
data T l :: *
type V l :: *
label :: T l -> String
val :: T l -> V l
instance TC "age" where
data T "age" = T___age Int
type V "age" = Int
label x = "age"
val (T___age x) = x