根据关联的类型族实例

时间:2015-09-27 21:59:45

标签: haskell

作为思想实验的一部分, 我正在尝试强制执行以下属性 对于与类型TC相关联的类型族T 在哈斯克尔:

  1. 具有不同标签的T家庭成员的类型不同。
  2. 具有相同标签的所有T包含相同类型的值。 (即标签字符串表示返回类型val
  3. 具有以下功能:

    1. 可以在运行时查看T标签的字符串表示形式,但不能在运行时更改。
    2. 有什么想法吗?

      我最接近编译的是以下内容。它满足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"
      

      感谢您提供任何帮助。

1 个答案:

答案 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