理解HList的这个定义 [英] Understanding this definition of HList

查看:81
本文介绍了理解HList的这个定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Haskell比较新,我试图理解 HList

 数据实例HList'[] = HNil 
newtype实例HList(x':xs)= HCons1(x,HList xs)
模式HCons x xs = HCons1(x,xs)
pre>

我有几个具体问题:


  • 什么是我看到了'[] (x':xs)语法?它几乎看起来像是在可变参数类型参数上的模式匹配,但是我从未见过这种语法,也不熟悉Haskell中的可变参数类型参数。我想这是 GHC的家庭类型的一部分,但我没有看到任何关于这个在链接的页面上,并且在Google中搜索语法相当困难。

  • 使用 newtype HCons1 之外,c $ c>具有元组的声明(而不是 data 两个字段的声明) 首先,您缺少部分定义: data family 声明本身。

     数据族HList(l :: [*] )
    数据实例HList'[] = HNil
    newtype实例HList(x':xs)= HCons1(x,HList xs)

    这被称为 数据族 (可在 TypeF下找到) $ b

     模式HCons x xs = HCons1(x,xs)

    这是一个双向模式(可在 PatternSynonyms 扩展名下使用) 。


    什么是'[] ( x':xs)语法

    当您看到 '标记在构造函数前面,它表示它们的提升类型级别对应方。作为一种语法便利,提升的列表和元组也只需要额外的记号(我们仍然可以为空的类型级别列表写'[] >并且':为类型级缺点,所有这些都可以通过 DataKinds 扩展名获得。


    除了避免使用元组(而不是带有两个字段的数据声明)使用 newtype 声明有任何意义拳击 HCons1


    是的,要确保 HList 具有代表性的角色 ,这意味着你可以在> HList s 1 之间强制执行。这只是一个太复杂的问题,不能解释一个答案,但这里是事情当我们有

     数据实例HList(x':xs)= HCons x(HList xs )

    而不是 newtype实例(和没有模式)。考虑下面的 newtype s,它们代表性地等同于 Int Bool ()分别

      newtype MyInt = MyInt Int 
    newtype MyBool = MyBool Bool
    newtype MyUnit = MyUnit()

    回想一下,我们可以使用 coerce 自动换行或打开这些类型。我们希望能够做同样的事情,但是对于整个 HList

      ghci的> l =(HCons 3(HCons True(HCons()HNil))):: HList'[Int,Bool,()] 
    ghci> l'= coerce l :: HList'[MyInt,MyBool,MyUnit]

    code> newtype instance variant,但不是数据实例,因为角色。 (更多关于此处。)






    1 从技术上讲,数据族没有作用实例的角色可以是不同的 / newtype - 这里我们只需要 HCons 情况为代表性,因为这是被强制执行的情况。 查看此Trac票券


    I'm relatively new to Haskell, and I'm trying to understand one of the definitions of HList.

    data instance HList '[] = HNil
    newtype instance HList (x ': xs) = HCons1 (x, HList xs)
    pattern HCons x xs = HCons1 (x, xs)
    

    I have a couple specific questions:

    • What is the '[] and (x ': xs) syntax I'm seeing? It almost looks like it's pattern matching on variadic type parameters, but I have never seen this syntax before, nor am I familiar with variadic type parameters in Haskell. I would guess this is part of GHC's Type Families, but I don't see anything about this on the linked page, and it's rather hard to search syntax in Google.

    • Is there any point in using a newtype declaration with a tuple (instead of a data declaration with two fields) besides avoiding boxing of HCons1?

    解决方案

    First, you are missing part of the definition: the data family declaration itself.

    data family HList (l :: [*])
    data instance HList '[] = HNil
    newtype instance HList (x ': xs) = HCons1 (x, HList xs)
    

    This is called a data family (available under the TypeFamilies extension).

    pattern HCons x xs = HCons1 (x, xs)
    

    This is a bidirectional pattern (available under the PatternSynonyms extension).

    What is the '[] and (x ': xs) syntax I'm seeing?

    When you see ' marks in front of constructors, it is to denote their promoted type-level counterparts. As a syntactic convenience, promoted lists and tuples also just need the extra tick (and we still get to write '[] for the empty type-level list and ': for the type level cons. All of this is available through the DataKinds extension.

    Is there any point in using a newtype declaration with a tuple (instead of a data declaration with two fields) besides avoiding boxing of HCons1?

    Yes, it is to make sure that HList has a representational role, which means you can coerce between HLists1. This is a bit too involved to explain in just an answer, but here is an example of where things don't go as we want when we have

     data instance HList (x ': xs) = HCons x (HList xs)
    

    instead of the newtype instance (and no pattern). Consider the following newtypes which are representationally equivalent to Int, Bool, and () respectively

    newtype MyInt = MyInt Int
    newtype MyBool = MyBool Bool
    newtype MyUnit = MyUnit ()
    

    Recall we can use coerce to wrap or unwrap these types automatically. Well, we'd like to be able to do the same thing, but for a whole HList:

    ghci> l  = (HCons 3 (HCons True (HCons () HNil))) :: HList '[Int,   Bool,   ()]
    ghci> l' = coerce l                               :: HList '[MyInt, MyBool, MyUnit]
    

    This works with the newtype instance variant, but not the data instance one because of the roles. (More on that here.)


    1 technically, there is no role for a data family as a whole: the roles can be different for each instance/newtype - here we only really need the HCons case to be representational, since that's the one that gets coerced. Check out this Trac ticket.

    这篇关于理解HList的这个定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆