3

私は注釈付きのASTを持つようにしたいので、私はFixを使用して これらの再帰的なデータ構造を定義した:Haskell Labeled AST:(Show1(Label a))のインスタンスがありません。インスタンスを作成する方法は?

data Term a 
    = Abstraction Name a 
    | Application a a 
    | Variable Name 
    deriving (Read,Show,Eq,Functor,Foldable,Traversable) 
data Label a b 
    = Label a (Term b) 
    deriving (Read,Show,Eq,Functor,Foldable,Traversable) 
newtype Labeled a 
    = Labeled (Fix (Label a)) 
    deriving (Show) 

私はLabeled ashowにできるようにしたいが、コンパイラが幸せではない:

No instance for (Show1 (Label a)) 
arising from the first field of `Labeled' (type `Fix (Label a)') 

class Show1とはどのように定義し、適切なインスタンスを定義してLabeled aを表示することができますか?

+0

'Show 1 'は 'Data.Functor.Classes'で定義されているようです。 'Labeled(Fix a(Label a)) 'の' Label'が部分的に適用されています。これは 'Show1'が扱うものです。 – ryachza

答えて

1

Show1は、「高次の表示可能品」と呼ばれるもののクラスです。引数が表示可能な場合に表示可能な型コンストラクタです。緩い高速と-推論の目的のために、あなたは(もshowsPrec1参照)大体このように宣言されているようShow1と考えることができます:

class Show1 f where 
    show1 :: Show a => f a -> String 

ここShow1について考える別の有用な不正確-が、-方法です。私はthe constraints library"entailment" operatorを使用して、の場合は、f aShowのインスタンスであることを宣言しています。このモデルは少しシンプルですが、あまり実用的ではありません。とにかく

class Show1 f where 
    show1 :: Show a :- Show (f a) 

引数が高次showableであれば、Fix :: (* -> *) -> *はshowableです。 the source codeから:

instance Show1 f => Show (Fix f) where 
    showsPrec d (Fix a) = 
    showParen (d >= 11) 
     $ showString "Fix " 
     . showsPrec1 11 a 

recursion-schemesの作者は...彼らのShowインスタンスを書くこと

deriving instance Show (f (Fix f)) => Show (Fix f) 

StandaloneDerivingを使用している可能性が...しかし、この文脈ではUndecidableInstancesが必要です。

与えられたファンクタのShow1インスタンスを書き込む最も簡単な方法は、the deriving-compat libraryTemplate Haskell helperを使用することです。

{-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable #-} 
{-# LANGUAGE TemplateHaskell #-} 

import Text.Show.Deriving 
import Data.Functor.Foldable 


type Name = String 
data Term a 
    = Abstraction Name a 
    | Application a a 
    | Variable Name 
    deriving (Read, Show, Eq, Functor, Foldable, Traversable) 

deriveShow1 ''Term 

data Label a b = Label a (Term b) 
    deriving (Read, Show, Eq, Functor, Foldable, Traversable) 

deriveShow1 ''Label 

newtype Labeled a = Labeled (Fix (Label a)) deriving (Show) 

これは

instance Show1 Term 
instance Show a => Show1 (Label a) 

あなたはLabeled年代から派生したインスタンスのためにしたいまさにあなたに与えて、次のインスタンスを生成します:。

instance Show a => Show (Labeled a) 

(PSあなたが使用して考えがありますboundのようなライブラリで、あなたの用語の名前とバインダーを管理していますか?)

関連する問題