use*_*376 5 haskell abstract-syntax-tree recursive-datastructures deriving
我想要一个带注释的 AST,所以我使用Fix
以下定义了这些递归数据结构:
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)
Run Code Online (Sandbox Code Playgroud)
我希望能够show
a Labeled a
,但编译器不高兴:
Run Code Online (Sandbox Code Playgroud)No instance for (Show1 (Label a)) arising from the first field of `Labeled' (type `Fix (Label a)')
什么是类Show1
以及如何定义适当的实例以显示Labeled a
?
Show1
是您可能称之为“高阶可显示对象”的类:只要其参数可显示,该类型构造函数就可显示。出于快速和宽松推理的目的,您可以认为Show1
大致是这样声明的(另请参阅showsPrec1
):
class Show1 f where
show1 :: Show a => f a -> String
Run Code Online (Sandbox Code Playgroud)
这是另一种不准确但有用的思考方式Show1
。我正在使用库constraints
的“蕴涵”运算符来声明 that应该是每当是f a
的一个实例。这个模型有点简单,但可能不太实用。Show
a
class Show1 f where
show1 :: Show a :- Show (f a)
Run Code Online (Sandbox Code Playgroud)
无论如何,Fix :: (* -> *) -> *
如果它的参数是高阶可显示的,则它是可显示的。从源代码来看:
instance Show1 f => Show (Fix f) where
showsPrec d (Fix a) =
showParen (d >= 11)
$ showString "Fix "
. showsPrec1 11 a
Run Code Online (Sandbox Code Playgroud)
作者本recursion-schemes
可以用来StandaloneDeriving
编写他们的Show
实例......
deriving instance Show (f (Fix f)) => Show (Fix f)
Run Code Online (Sandbox Code Playgroud)
...但是这个上下文需要UndecidableInstances
.
为给定函子编写实例的最简单方法Show1
是使用库deriving-compat
的Template Haskell 帮助程序。
{-# 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)
Run Code Online (Sandbox Code Playgroud)
这将生成以下实例,
instance Show1 Term
instance Show a => Show1 (Label a)
Run Code Online (Sandbox Code Playgroud)
为您提供您想要的Labeled
派生实例:
instance Show a => Show (Labeled a)
Run Code Online (Sandbox Code Playgroud)
(PS。您是否考虑过使用类似的库bound
来管理您的术语语言中的名称和活页夹?)
归档时间: |
|
查看次数: |
222 次 |
最近记录: |