类型同类对类型实例有什么影响? GHC中的TypeSynonymInstances编译指示是做什么的? [英] What is the effect of type synonyms on instances of type classes? What does the TypeSynonymInstances pragma in GHC do?

查看:102
本文介绍了类型同类对类型实例有什么影响? GHC中的TypeSynonymInstances编译指示是做什么的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读的是真实世界的Haskell 第151页,我盯着下面的文章一个多小时:


回想一下,String是
[Char]的同义词,后者又是类型[a]
,其中Char代替类型
参数a。根据Haskell 98的
规则,当我们编写一个实例
时,我们不允许提供
类型来代替类型参数。换句话说,
对于我们来说为[a]写一个
实例是合法的,但对于[Char]则不是。
16个评论5335


它简直不会沉入其中。盯着 RWH第6章的(免费没有盗版的)副本我看到其他人很多 真的很痛苦。我仍然无法从评论中了解它...



首先,所有关于这一点的事情都让我困惑,所以如果你觉得你可以解释关于这段经文的任何内容, $ b $> b


  • Int 是一个数据构造函数
  • 字符串是一个数据构造函数 AND 类型同义词



现在我无法回答这些问题:


  1. 为什么类型同义词排除了制作键入一个类型成员(我正在寻找可能涉及编译或实现类型同义词的一些原因)?

  2. 为什么语言的设计者不想要语法(我要求推理不是广泛的理论或unicode数学符号)。
  3. 我看到这行类型[a],其中Char代替类型参数a ,我想知道为什么我不能用它代替它类型a,其中Int代替类型参数a


$ b $我认为这个问题的一部分是,两个很大程度上无关的限制正在发挥作用: / p>


  • 没有类型同义词实例意味着实例只能是使用 data newtype ,而不是 type 。这禁止字符串,但不是 [Char]

  • 没有灵活的实例意味着实例只能提到一种不是变量的类型,只能将该类型用作类型构造函数。这禁止可能是Int f Int ,但不是也许一个



以下是GHCi有关 Int Char String

 数据Char = GHC.Types.C#GHC.Prim.Char#
data Int = GHC.Types.I#GHC.Prim.Int#
type String = [Char]

Int Char 都是没有类型变量参数的简单类型;不存在任何类型构造函数,因此您可以非常自由地使用它们。



然而,字符串在这两个计数都失败。它是一个不允许的类型同义词,它也是一个应用于非变量的类型构造函数,即应用于Char的列表类型构造函数。



作为比较,请注意 [a] 也许一个 ab 在实例中都是有效的,但 [Int] , Maybe [a] ,并且任何一个字符串a 都被禁止;希望你现在可以明白为什么。



至于你的直接问题,我不知道这样设计语言的原始动机是什么,而且我在没有办法做出关于最佳实践的权威性陈述,但对于我自己的个人编码,我并不会毫不犹豫地使用这些编译指示:

 <$ $ b $ { - #LANGUAGE TypeNewtypeDeriving# - } 
{ - #LANGUAGE EmptyDataDecls# - }
{ - #LANGUAGE类型同义词实例# - }
{ - #LANGUAGE FlexibleInstances# - }
{ - #LANGUAGE FlexibleContexts# - }

您可以随时查看使用pragmas的软件包。看起来,灵活的实例确实得到了相当的使用,并且来自可尊敬的包(例如,Parsec的源代码中有几个命中)。


I'm reading Real World Haskell Pg 151, and I've stared at the following passage for over an hour:

Recall that String is a synonym for [Char], which in turn is the type [a] where Char is substituted for the type parameter a. According to Haskell 98's rules, we are not allowed to supply a type in place of a type parameter when we write an instance. In other words, it would be legal for us to write an instance for [a], but not for [Char]. 16 comments 5335

It simply isn't sinking in. Staring at the the (free not pirated) copy of RWH chapter 6 I see a lot of other people are really suffering with this. I still don't understand it from the comments...

Firstly, everything about this confuses me, so please if you feel you can explain anything about this passage, or TypeSynonymInstances please do.

Here is my problem:

  • Int is a data constructor
  • String is a data constructor AND type synonym

Now I can't answer these questions:

  1. Why would a type synonym preclude the making the type a member of a type class (I'm looking for some reason which probably relates to compilation or implimentation of a type synonym)?
  2. Why did the designers of the language, not want this syntax (I'm asking for reasoning not extensive theory or unicode math symbols).
  3. I see this line "the type [a] where Char is substituted for the type parameter a", and I want to know why I can't substitute it for this "the type a where Int is substituted for the type parameter a".

Thanks!

解决方案

I think part of the issue is that two, largely unrelated, restrictions are in play:

  • No type synonym instances means that instances can only be things declared with data or newtype, not type. This forbids String, but not [Char].
  • No flexible instances means that instances can only mention one type that isn't a variable, and only that type can be used as a type constructor. This forbids Maybe Int and f Int, but not Maybe a.

Here's what GHCi says about Int, Char, and String:

data Char = GHC.Types.C# GHC.Prim.Char#
data Int = GHC.Types.I# GHC.Prim.Int#
type String = [Char]

Int and Char are both simple types without type variable parameters; there's no type constructor involved, so you can make instances with them pretty much freely.

String, however, fails on both counts. It's a type synonym, which isn't allowed, and it's also a type constructor applied to a non-variable, namely the list type constructor applied to Char.

For comparison, note that [a], Maybe a, and Either a b are all valid in instances, but [Int], Maybe [a], and Either String a are forbidden; hopefully you can now see why.

As for your direct questions, I don't know what the original motivations were for designing the language that way, and I'm in no way qualified to make authoritative statements about "best practices", but for my own personal coding I don't really hesitate to use these pragmas:

{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}

You could always go look at packages that use pragmas. Flexible instances, it seems, do get a fair amount of use, and from "respectable" packages (there's a couple hits in the source for Parsec, for instance).

这篇关于类型同类对类型实例有什么影响? GHC中的TypeSynonymInstances编译指示是做什么的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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