考虑以下类型声明:
deriving Show
现在为此编写一个Foobar x
实例。我敢说你!
我随便写了x y
,希望GHC做到这一点。但它抱怨它无法做到。 "可怜的傻瓜",我想,并继续自己定义。但是......嗯...哦,实际上这很有意思......显然y
仅在Show
可展示SELECT
(CAST(MAX(Id) AS DECIMAL(38,0)) + 1) AS 'New ID'
FROM database
WHERE Id NOT LIKE '%[^0-9]%' --filters out non-numeric ID values
AND (LEN(Id) + 1) < 39 --ensures ID is less than length 39
...或者......时显示。 ......那样的...... aaargh!
现在我确定我不可能成为第一个定义此类型的人。我不能成为第一个想要SELECT
(CAST(MAX(CAST(Id AS DECIMAL(38,0))) AS DECIMAL(38,0)) + 1) AS 'New ID'
FROM database
WHERE Id NOT LIKE '%[^0-9]%'
AND (LEN(Id) + 1) < 39
实例的人。所以有人必须弄清楚如何做到这一点。
答案 0 :(得分:6)
如果您只是指定明显的约束 - 并添加一些必要的语言编译指示 - 一切正常。要使Foobar
可显示,Foo
的字段必须是可显示的,因此我们需要Show (x (Foobar x))
约束。如果我们要求这样做,一切都会成功:
{-# LANGUAGE FlexibleContexts, UndecidableInstances, StandaloneDeriving #-}
data Foobar x = Foo (x (Foobar x))
deriving instance Show (x (Foobar x)) => Show (Foobar x)
然后:
λ> print $ Foo [Foo [], Foo [Foo []]]
Foo [Foo [],Foo [Foo []]]
λ> data SL a = S String | L [a] deriving Show
λ> print $ Foo (L [Foo (S "a"), Foo (L [Foo (S "b"), Foo (L []), Foo (S "c")])])
Foo (L [Foo (S "a"),Foo (L [Foo (S "b"),Foo (L []),Foo (S "c")])])
我对这项工作有点惊讶,但并不过分: - )
顺便提一下,如果您尝试为Show
派生Foobar
,这正是GHC所要求的:
λ> data Foobar x = Foo (x (Foobar x)) deriving Show
<interactive>:2:45:
No instance for (Show (x (Foobar x)))
arising from the first field of ‘Foo’ (type ‘x (Foobar x)’)
Possible fix:
use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
When deriving the instance for (Show (Foobar x))
我们所要做的只是使用StandaloneDeriving
并准确指定约束!
另外,要明确的是,StandaloneDeriving
部分是可选的 - 它没有做任何魔术,并且实例并不难以手工编写:
instance Show (x (Foobar x)) => Show (Foobar x) where
showsPrec p (Foo x) = showParen (p > app_prec) $
showString "Foo " . showsPrec (app_prec + 1) x
where app_prec = 10 :: Int
答案 1 :(得分:6)
以下是没有扩展的方法:
data Foobar x = Foo (x (Foobar x))
class Show1 f where
showsPrec1 :: Show a => Int -> f a -> ShowS
instance Show1 f => Show (Foobar f) where
showsPrec n (Foo v) = ("Foo " ++) . showsPrec1 n v -- doesn't handle n correctly because that's not the point of the question and would only distract from the actual important idea
Show1
类(以及标准类型的一些实例)也可用on Hackage。定义它的模块使用了一些扩展 - 但只是为了减少样板,而不是为了使旧的Haskell2010无法做任何事情。
答案 2 :(得分:1)
好的,所以在玩代码时,我找到了一种的方法:
$csv->say ($out, [@pairs, @result]);
但是有一些问题。
instance (Functor f, Show (f String)) => Show (Foobar f) where
show = fold show
fold :: Functor f => (f x -> x) -> Foobar f -> x
fold f (Foo x) = f (fmap (fold f) x)
构造函数,并且引用了子表达式。)Foo
才能工作。 (!)UndecidableInstances
以包含show
构造函数,但GHC恐慌(!!!)我不知道你只是通过编写用户代码来实际崩溃GHC ......显然你可以做到。
Foo
我猜它被称为&#34;不可判断&#34;因为某种原因! O_O