混合类型类和类型族时会出现问题 [英] Problem when mixing type classes and type families

查看:114
本文介绍了混合类型类和类型族时会出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这段代码编译得很好:

  { - #LANGUAGE MultiParamTypeClasses,FunctionalDependencies,FlexibleInstances,
UndecidableInstances,FlexibleContexts, EmptyDataDecls,ScopedTypeVariables,
TypeOperators,TypeSynonymInstances,TypeFamilies# - }
class Sel asb其中
类型Res asb :: *

实例Sel asb其中
类型Res asb =(s->(b,s))

实例Sel as(b->(c,a))其中
类型Res as(b-> (c,a))=(b-> s->(c,s))

但是一旦我添加了R谓词ghc失败:

$ $ $ $ $ $ $ $ $#$ L $ {$# b UndecidableInstances,FlexibleContexts,EmptyDataDecls,ScopedTypeVariables,
TypeOperators,TypeSynonymInstances,TypeFamilies# - }
class Sel asb其中
类型Res asb :: *

实例Sel asb其中
类型Res asb =(s - >(b,s))

class R a其中
类型Rec a :: *
cons :: a - > Rec a
elim :: Rec a - > (b - >(c,Rec a))其中
类型Res为(b-> (c,s))

抱怨:

 实例中的非法类型同义词族应用程序:
b - > (c,Rec a)
在`Sel as(b - >(c,Rec a))'的实例声明中'

这是什么意思,并且(最重要的是)我该如何修复它?

谢谢
<类型族是单向的:你可以将 Rec a 扩展为它的计算类型,但是你不能(唯一地)从扩展回到 Rec a 。这使得类型函数的应用程序不适用于实例签名,因为它们永远不会触发实例应用。



您可以尝试:

 实例Rec a〜reca => Sel as(b->(c,reca))

这意味着别的东西:函数 b - > (c,reca)是一个实例,然后当它不可撤销地匹配时,编译器检查 Rec a〜reca 。但是这可能足以满足您的需求。


This code compiles fine:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances,
  UndecidableInstances, FlexibleContexts, EmptyDataDecls, ScopedTypeVariables,
  TypeOperators, TypeSynonymInstances, TypeFamilies #-}
class Sel a s b where
  type Res a s b :: *

instance Sel a s b where
  type Res a s b = (s -> (b,s))

instance Sel a s (b->(c,a)) where
  type Res a s (b->(c,a)) = (b -> s -> (c,s))

but as soon as I add the R predicate ghc fails:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances,
  UndecidableInstances, FlexibleContexts, EmptyDataDecls, ScopedTypeVariables,
  TypeOperators, TypeSynonymInstances, TypeFamilies #-}
class Sel a s b where
  type Res a s b :: *

instance Sel a s b where
  type Res a s b = (s -> (b,s))

class R a where
  type Rec a :: *
  cons :: a -> Rec a
  elim :: Rec a -> a
instance Sel a s (b->(c,Rec a)) where
  type Res a s (b->(c,Rec a)) = (b -> s -> (c,s))

complaining that:

    Illegal type synonym family application in instance:
        b -> (c, Rec a)
    In the instance declaration for `Sel a s (b -> (c, Rec a))'

what does it mean and (most importantly) how do I fix it?

Thanks

解决方案

Type families are one-way: you can expand Rec a to its computed type, but you cannot (uniquely) go from the expansion back to Rec a. This makes applications of type functions unsuitable for instance signatures, as they can never trigger the instance to apply.

You could try instead:

instance Rec a ~ reca => Sel a s (b->(c,reca))

This means something else: it says any function b -> (c, reca) is an instance, and then when it has irrevocably matched, the compiler checks that Rec a ~ reca. But this might be good enough to do want in your case.

这篇关于混合类型类和类型族时会出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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