混合类型类和类型族时出现问题

Giu*_*ore 9 haskell typeclass type-families

这段代码很好编译:

{-# 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))
Run Code Online (Sandbox Code Playgroud)

但是只要我添加R谓词ghc失败:

{-# 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))
Run Code Online (Sandbox Code Playgroud)

抱怨说:

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

它是什么意思和(最重要的)我该如何修复它?

谢谢

Mar*_*ijn 12

类型族是单向的:您可以扩展Rec a到其计算类型,但不能(唯一)从扩展返回到Rec a.这使得类型函数的应用程序不适合签名,因为它们永远不会触发要应用的实例.

你可以试试:

instance Rec a ~ reca => Sel a s (b->(c,reca))
Run Code Online (Sandbox Code Playgroud)

这意味着别的东西:它说任何函数b -> (c, reca)都是一个实例,然后当它不可撤销地匹配时,编译器会检查它Rec a ~ reca.但在你的情况下,这可能足够好了.