当前位置:  开发笔记 > 编程语言 > 正文

实例实现的模式匹配

如何解决《实例实现的模式匹配》经验,为你挑选了1个好方法。

我正在尝试实现数据类型的show方法.

data OptionList a b = EmptyOpt | OptionList { optListHead :: a, optListTail :: b } deriving (Read)

instance (Show a, Show b) => Show (OptionList a b) where
    show (OptionList a EmptyOpt) = "{" ++ (show a) ++"}"
    show (OptionList EmptyOpt b) = "{" ++ (show b) ++"}"
    show (OptionList a b) = "{"++ (show a) ++ ", " ++ (show b) ++"}"
    show EmptyOpt = ""

我希望OptionList不显示逗号,如果其中一个ab具有由EmptyOpt构造的值.但编译器显示以下错误:

OptionList.hs:11:28:
    Couldn't match expected type ‘b’
                with actual type ‘OptionList t0 t1’
      ‘b’ is a rigid type variable bound by
          the instance declaration at OptionList.hs:10:10
    Relevant bindings include
      show :: OptionList a b -> String (bound at OptionList.hs:11:9)
    In the pattern: EmptyOpt
    In the pattern: OptionList a EmptyOpt
    In an equation for ‘show’:
        show (OptionList a EmptyOpt) = "{" ++ (show a) ++ "}"

OptionList.hs:12:26:
    Couldn't match expected type ‘a’
                with actual type ‘OptionList t2 t3’
      ‘a’ is a rigid type variable bound by
          the instance declaration at OptionList.hs:10:10
    Relevant bindings include
      show :: OptionList a b -> String (bound at OptionList.hs:11:9)
    In the pattern: EmptyOpt
    In the pattern: OptionList EmptyOpt b
    In an equation for ‘show’:
        show (OptionList EmptyOpt b) = "{" ++ (show b) ++ "}"

更新:OptionList应该是类似无类型列表的东西.

(+:) :: a -> b -> (OptionList a b)
infixr 5 +:
t1 +: t2 = OptionList t1 t2

所以,像这样的列表0 +: "test" +: True将被定义为OptionList Int (OptionList String (OptionList Bool EmptyOpt))和将被定义show{0, {"test", {True}}}



1> adamse..:

更新的更新.如果您愿意打开某些扩展程序,可以使其正常工作:

{-# LANGUAGE FlexibleInstances #-}

data EmptyOpt = EmptyOpt

data OptionList a b =
  OptionList a b
  deriving (Read)

instance (Show a, Show b) => Show (OptionList a b) where
  show (OptionList a b) = "{ " ++ show a ++ ", " ++ show b ++ " }"

instance {-# OVERLAPPING  #-} (Show a) => Show (OptionList a EmptyOpt) where
  show (OptionList a EmptyOpt) = "{ " ++ show a ++ " }"

(+:) :: a -> b -> (OptionList a b)
infixr 5 +:
t1 +: t2 = OptionList t1 t2

test = 0 +: "test" +: True +: EmptyOpt

但我个人会尝试用类似的东西

data Option = B Bool | I Int | S String
data OptionsList = Empty | OptionsList Option OptionsList

你的麻烦是,例如,头((Show a, Show b) => Show (OptionList a b))说,要实现ShowOptionList a b地方ab任何类型的Show实例,但在你执行你要求这两个ab实际上都是类型OptionList.

也许您会将类型更改为更像普通列表:

data OptionList a
  = EmptyOpt
  | OptionList { optListHead :: a
              ,  optListTail :: OptionList a}
  deriving (Read)

然后你可以有一个实例:

instance (Show a) => Show (OptionList a) where
  show (OptionList a EmptyOpt) = "{" ++ show a ++"}"
  show (OptionList a b) = "{"++ show a ++ ", " ++ show b ++"}"
  show EmptyOpt = ""

推荐阅读
雯颜哥_135
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有