变量参数,使用类型系列而不是多参数类型类 [英] Variadic arguments, using Type Families instead of Multi-param Typeclasses

查看:137
本文介绍了变量参数,使用类型系列而不是多参数类型类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  class ListResultMult ra其中
lstM :: a - > [a] - > r

listM :: ListResultMult r a => a - > r
listM a = lstM a []


实例ListResultMult r a => ListResultMult(a - > r)a其中
lstM a as x = lstM x $ a:as

实例ListResultMult [a] a其中
lstM a as =反向$ a:as

instance显示a => ListResultMult(IO())a其中
lstM a as = print。反向$ a:作为

以下是我尝试使用TypeFamilies(TypeSynonymInstances不起作用):

  class ListResultFam r其中
类型Elem r :: *
lstF :: Elem r - > [Elem r] - > r

listFam :: ListResultFam r => Elem r - > r
listFam a = lstF a []


- 实例中的非法类型同义词族应用程序:Elem r - > r
- 在ListResultFam(Elem r - > r)的实例声明中'
实例ListResultFam r => ListResultFam(Elem r - > r)其中
type Elem(Elem r - > r)= Elem r
lstF a as x = lstF x $ a:as

实例ListResultFam [a]其中
类型Elem [a] = a
lstF a as =反向$ a:as

有没有什么办法可以通过Type家族来实现?为什么这是一个非法类型的同义词族应用程序?

解决方案

类型族不是多参数类型类的替代品,而是他们取代了功能依赖。

这是因为类型系列允许从一种类型映射到另一种类型,这与多参数类型类的功能依赖关系类似。即:

  class Collection col e | col  - > e其中
getHead :: col - > e

实例集合[a] a其中
getHead = head



<可以用类型族来表示:

  class Collection col其中
类型CollectionHead col :: *
getHead :: col - > CollectionHead col

实例集合[a]其中
类型CollectionHead [a] = a
getHead = head

然而,它们不能替代没有函数依赖关系的多参数类型类。例如

  class Converter a b其中
convert :: a - > b

实例Converter Int字符串其中
convert = show

实例Converter Int [Int]其中
convert x = [x]

不能通过删除b参数和使用类型族来完成。你可以这样做:

  class转换器a其中
类型目标a :: *
转换:: a - >定位

实例Converter Int其中
类型Target Int = String
convert = show

但是不可能写第二个实例,因为它需要一个重复的实例 Converter Int




关于您的程序,您可以立即看到没有函数依赖关系,只有多个参数类型类。你为此不能做一个直接的转换,以此类型的家庭。


Here's what I've got, expressed with MultiParamTypeClasses:

class ListResultMult r a where
  lstM :: a -> [a] -> r

listM :: ListResultMult r a => a -> r
listM a = lstM a []


instance ListResultMult r a => ListResultMult (a -> r) a where
  lstM a as x = lstM x $ a:as

instance ListResultMult [a] a where
  lstM a as = reverse $ a:as

instance Show a => ListResultMult (IO ()) a where
  lstM a as = print . reverse $ a:as

Here's what I tried, using TypeFamilies (TypeSynonymInstances didn't help):

class ListResultFam r where
  type Elem r :: *
  lstF :: Elem r -> [Elem r] -> r

listFam :: ListResultFam r => Elem r -> r
listFam a = lstF a []


-- Illegal type synonym family application in instance: Elem r -> r
-- in the instance declaration for `ListResultFam (Elem r -> r)'
instance ListResultFam r => ListResultFam (Elem r -> r) where
  type Elem (Elem r -> r) = Elem r
  lstF a as x = lstF x $ a:as

instance ListResultFam [a] where
  type Elem [a] = a
  lstF a as = reverse $ a:as

Is there any way to accomplish this with Type Families? Why is this an "illegal" type synonym family application?

解决方案

Type families aren't a replacement for multi param type classes, rather they replace functional dependencies.

This is because type families allow a mapping from one type to another, which is similar to what functional dependencies do with multi param type classes. Ie:

class Collection col e | col -> e where
   getHead :: col -> e

instance Collection [a] a where
   getHead = head

can be represented with type families as:

class Collection col where
  type CollectionHead col :: *
  getHead :: col -> CollectionHead col

instance Collection [a] where
   type CollectionHead [a] = a
   getHead = head

However they cannot replace a multi param type class without functional dependencies. Eg

class Converter a b where
  convert :: a -> b

instance Converter Int String where
  convert = show

instance Converter Int [Int] where
  convert x = [x]

Cannot be done by removing the b param and using type families. You could do something like this:

class Converter a where
   type Target a :: *
   convert :: a -> Target a

instance Converter Int where
   type Target Int = String
   convert = show

However it isn't possible to write the second instance, as it require a duplicate instance Converter Int.


With regards to your program, you can see instantly that there are no functional dependencies, just multiple parameter type classes. You therefor cannot do a straight conversion to type families with this.

这篇关于变量参数,使用类型系列而不是多参数类型类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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