我想要一个带注释的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)
我希望能show
Labeled a
,但编译器不满意:
No instance for (Show1 (Label a)) arising from the first field of `Labeled' (type `Fix (Label a)')
什么是课程Show1
,如何定义适当的实例才能展示Labeled a
?
答案 0 :(得分:2)
Show1
是你可以称之为“高阶showables”的类:类型构造函数,只要它们的参数可以显示就可以显示。出于快速和宽松推理的目的,您可以将Show1
视为大致相同的声明(另请参阅showsPrec1
):
class Show1 f where
show1 :: Show a => f a -> String
这是考虑Show1
的另一种不准确但有用的方法。我正在使用the constraints
library的"entailment" operator声明只要f a
,Show
就应该是a
的实例。这个模型有点简单,但可能不太实用。
class Show1 f where
show1 :: Show a :- Show (f a)
无论如何,如果Fix :: (* -> *) -> *
的参数是高阶可显示的,则instance Show1 f => Show (Fix f) where
showsPrec d (Fix a) =
showParen (d >= 11)
$ showString "Fix "
. showsPrec1 11 a
是可显示的。来自the source code:
recursion-schemes
StandaloneDeriving
的作者可以使用Show
撰写他们的deriving instance Show (f (Fix f)) => Show (Fix f)
个实例...
UndecidableInstances
...但此上下文需要Show1
。
为给定仿函数编写{-# 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)
实例的最简单方法是使用the deriving-compat
library的Template Haskell helper。
instance Show1 Term
instance Show a => Show1 (Label a)
这将生成以下实例,
Labeled
准确地为您提供instance Show a => Show (Labeled a)
派生实例的所需内容:
DECLARE @tbl TABLE (dat NVARCHAR(64))
INSERT INTO @tbl (dat) VALUES ('2017-06-30 09:40:05.130')
INSERT INTO @tbl (dat) VALUES ('26/4/2016 00:00:00')
INSERT INTO @tbl (dat) VALUES ('2017-08-21 12:52:23.063000000')
INSERT INTO @tbl (dat) VALUES ('5/4/2016 00:00:00')
DECLARE @cdat NVARCHAR(64)
DECLARE c CURSOR LOCAL FAST_FORWARD READ_ONLY FOR
SELECT dat FROM @tbl
OPEN c
FETCH NEXT FROM c INTO @cdat
WHILE @@fetch_status = 0 BEGIN
BEGIN TRY
/*convert and do the job*/
SELECT CONVERT(DATETIME2,@cdat)--into normal table
END TRY
BEGIN CATCH
/*handle failed conversions*/
SELECT @cdat --into failstable?
PRINT 'failed conversion, data:' + @cdat
END CATCH
FETCH NEXT FROM c INTO @cdat
END
CLOSE c
DEALLOCATE c
(PS。您是否考虑过使用像bound
这样的库来管理您的学期语言中的姓名和活页夹?)