Haskell 递归实例定义
我有一个递归数据定义:Haskell 递归实例定义,haskell,Haskell,我有一个递归数据定义: data Checked a = forall b. Checked (Either (Warning, Maybe (Checked b), a) a) 我需要递归地定义Show: instance (Show a) => Show (Checked a) where show (Right v) = show v show (Left (w, Nothing, v) = show w ++ show v show (Left (w, Just c
data Checked a = forall b. Checked (Either (Warning, Maybe (Checked b), a) a)
我需要递归地定义Show:
instance (Show a) => Show (Checked a) where
show (Right v) = show v
show (Left (w, Nothing, v) = show w ++ show v
show (Left (w, Just ch, v) = show w ++ show v ++ "caused by" ++ show ch --recursive here
GHC给予
Could not deduce (Show b) arising from a use of `show'
from the context (Show a)
bound by the instance declaration at Checked.hs:29:10-35
Possible fix:
add (Show b) to the context of
the data constructor `Checked'
or the instance declaration
In the second argument of `(++)', namely `show ch'
如果我在实例定义的约束中添加(显示b),GHC将给出:
Ambiguous constraint `Show b'
At least one of the forall'd type variables mentioned by the constraint
must be reachable from the type after the '=>'
In the instance declaration for `Show (Checked a)'
是否需要采取下一步来编译此文件?您需要向数据类型添加
Show b
限制:
data Checked a = forall b. Show b => Checked (Either (Warning, Maybe (Checked b), a) a)
instance Show a => Show (Checked a) where
show (Checked (Right v)) = show v
show (Checked (Left (w, Nothing, v))) = show w ++ show v
show (Checked (Left (w, Just ch, v))) = show w ++ show v ++ "caused by" ++ show ch
您需要向数据类型添加
Show b
限制:
data Checked a = forall b. Show b => Checked (Either (Warning, Maybe (Checked b), a) a)
instance Show a => Show (Checked a) where
show (Checked (Right v)) = show v
show (Checked (Left (w, Nothing, v))) = show w ++ show v
show (Checked (Left (w, Just ch, v))) = show w ++ show v ++ "caused by" ++ show ch
将
Show
约束添加到数据类型定义中
data Checked a = forall b. Show b => Checked (Either (Warning, Maybe (Checked b), a) a)
也可以将约束类型用作
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE ExistentialQuantification #-}
data Checked a c = forall b. c b => Checked (Either (Maybe (Checked b c), a) a)
instance (Show a) => Show (Checked a Show) where
show (Checked (Right v)) = show v
show (Checked (Left (Nothing, v))) = show v
show (Checked (Left (Just ch, v))) = show v ++ "caused by" ++ show ch
将
Show
约束添加到数据类型定义中
data Checked a = forall b. Show b => Checked (Either (Warning, Maybe (Checked b), a) a)
也可以将约束类型用作
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE ExistentialQuantification #-}
data Checked a c = forall b. c b => Checked (Either (Maybe (Checked b c), a) a)
instance (Show a) => Show (Checked a Show) where
show (Checked (Right v)) = show v
show (Checked (Left (Nothing, v))) = show v
show (Checked (Left (Just ch, v))) = show v ++ "caused by" ++ show ch
请注意@HaskellElephant已经更正了您的代码(应该在答案中而不是在您的问题中发布)。@AndrewC我认为错误与问题无关,所以我更正了它。我应该恢复吗?修缮由舍尔德·维舍尔回答。@Haskell。我自己差点把它还原了,但我想给你一个机会把你的编辑作为答案的一部分。如果您将其还原,请在Sjoerd的回答中添加一行,说明已选中的
应该在那里。(尚不清楚Sjoerd是否看到了原文或编辑后的版本。)我认为在答案中编辑一些微不足道的明显错误是可以的,但如果你在没有告诉提问者的情况下编辑了问题,他们可能不会注意到,他们将不必要地被蒙在鼓里。如果你真的回复了,请再次回复我,这样我就可以删除我的评论了。@AndrewC好吧,有一件事是问者是怎么想的,但是任何再次访问此帖子以了解问题内容的人都很难发现额外的错误。请注意,不仅仅是选中了额外的
,还有一个不匹配的括号、一个缺少的where
、一个错误的缩进,这将在您找到问题中的错误之前给您一个解析错误。我将还原编辑并将其作为答案。对不起,各位。我自己纠正了那些草率的错误。请注意@HaskellElephant已经更正了您的代码(应该在答案中而不是在您的问题中发布)。@AndrewC我认为这个错误与所问的问题无关,所以我更正了它。我应该恢复吗?修缮由舍尔德·维舍尔回答。@Haskell。我自己差点把它还原了,但我想给你一个机会把你的编辑作为答案的一部分。如果您将其还原,请在Sjoerd的回答中添加一行,说明已选中的
应该在那里。(尚不清楚Sjoerd是否看到了原文或编辑后的版本。)我认为在答案中编辑一些微不足道的明显错误是可以的,但如果你在没有告诉提问者的情况下编辑了问题,他们可能不会注意到,他们将不必要地被蒙在鼓里。如果你真的回复了,请再次回复我,这样我就可以删除我的评论了。@AndrewC好吧,有一件事是问者是怎么想的,但是任何再次访问此帖子以了解问题内容的人都很难发现额外的错误。请注意,不仅仅是选中了额外的
,还有一个不匹配的括号、一个缺少的where
、一个错误的缩进,这将在您找到问题中的错误之前给您一个解析错误。我将还原编辑并将其作为答案。对不起,各位。我自己纠正了那些草率的错误。把它归结为对奇妙的StackOverflowThank Sjoard的不熟悉,但有没有一种解决方案,我不必以这种方式污染Show?因为现在编译器要求在其他已检查的实例声明中显示a=>约束,例如与Show@RobertOnslow你能在没有存在量化的情况下管理吗?数据检查a b=…
会做什么?如果是这样的话,你可以在没有演出背景的情况下工作。或者,将整件事包装在GADT中能解决你所有的麻烦吗?@AndrewC我会先考虑检查a b。谢谢。@RobertOnslow您可以使用约束类型,并为其他情况传递无用的约束。请参阅我的答案了解用法。谢谢Sjoerd,但有没有一种解决方案可以让我不必用这种方式污染Show?因为现在编译器要求在其他已检查的实例声明中显示a=>约束,例如与Show@RobertOnslow你能在没有存在量化的情况下管理吗?数据检查a b=…
会做什么?如果是这样的话,你可以在没有演出背景的情况下工作。或者,将整件事包装在GADT中能解决你所有的麻烦吗?@AndrewC我会先考虑检查a b。谢谢。@RobertOnslow您可以使用约束类型,并为其他情况传递无用的约束。有关用法,请参见我的答案。