Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell派生Show实例_Haskell_Show_Deriving - Fatal编程技术网

Haskell派生Show实例

Haskell派生Show实例,haskell,show,deriving,Haskell,Show,Deriving,我在玩一棵红黑的树: -- Taken from Okasaki 1999 module RedBlackTree where --node coloring data --a node is R (red) or B (black) data Color = R | B --tree constructor --a RBT can be E (empty) or be T (a non empty tree) data RBT e = E | T Color (RBT e) e (RBT

我在玩一棵红黑的树:

-- Taken from Okasaki 1999
module RedBlackTree where

--node coloring data
--a node is R (red) or B (black)
data Color = R | B

--tree constructor
--a RBT can be E (empty) or be T (a non empty tree)
data RBT e = E | T Color (RBT e) e (RBT e)

--set operations on tree
type Set a = RBT a

--define an empty set
empty :: Set e
empty = E

--define a member of a set
--Sees if an item of type e is
--in a set if type e elements
member :: (Ord e) => e -> Set e -> Bool
member x E = False
member x (T _ a y b) | x <  y = member x a -- if less, go left
                     | x == y = True
                     | x >  y = member x b -- if more, go right


--tree operations
--Insert an element
insert :: (Ord e) => e -> Set e -> Set e
insert x s = makeBlack (ins s)
    where ins E = T R E x E --basically the typical BST insert
          ins (T color a y b) | x <  y = balance color (ins a) y b
                              | x == y = T color a y b
                              | x >  y = balance color a y (ins b)
          makeBlack (T _ a y b) = T B a y b --inserts a black node

-- balance operations
--case 1:
balance B (T R (T R a x b) y c) z d = T R (T B a x b) y (T B c z d)
--case 2:
balance B (T R a x (T R b y c)) z d = T R (T B a x b) y (T B c z d)
--case 3:
balance B a x (T R (T R b y c) z d) = T R (T B a x b) y (T B c z d)
--case 4:
balance B a x (T R b y (T R c z d)) = T R (T B a x b) y (T B c z d)
--generic balancing operation
balance color a x b = T color a x b
下面的错误消息告诉我没有显示
Set Char
的实例:

<interactive>:116:1:
No instance for (Show (Set Char)) arising from a use of `print'
Possible fix: add an instance declaration for (Show (Set Char))
In a stmt of an interactive GHCi command: print it
尝试使用
加载时,我收到以下错误消息:l

:l红色-黑色-树.hs [1/1]编译RedBlackTree(red-black-tree.hs,已解释)


我认为我试图做的事情存在一些问题,但我似乎无法从可用的文档中找到答案。

您没有任何花哨的扩展正在使用,因此您应该能够使用内置的
派生
机制来
显示

为了自动为数据类型派生
Show
实例,类型定义中使用的所有类型也必须具有
Show
实例。只需在所有
数据的末尾添加
派生(显示)
。您可能希望养成向所有
数据
类型中添加
派生(Eq,Show)
的习惯,因为您几乎总是希望类型的结构相等性测试和可显示性


此外,不能为类型别名创建任何排序的类实例,只能为类型创建。关键字
type
定义类型别名,而不是新类型。如果为您的
RBT a
类型创建
Show
实例,它将自动用于您声明为
Set a
的任何内容,因为
Set a
只是
RBT a
的别名,您的实例代码已被破坏:

instance Show Set where
    show (Set Char) = show Char
  • 编译器抱怨
    Set
    不是一个数据构造函数,它不是-它是一个类型同义词名称。因此,您在模式中错误地使用了
    Set
    。您可以在那里使用数据构造函数-对于
    RBT
    ,数据构造函数是
    T
    E

  • 您的实例声明类型不正确:
    Set
    RBT
    的同义词,
    RBT
    有一个类型参数,即它是从一个类型到另一个类型的函数,类型签名为
    *->*
    。但是
    Show
    实例需要一个没有参数的类型,它是一个类型而不是一个类型构造函数,类型是
    *
    ,而不是您提供的
    *->*
    。因此,您应该通过提供
    instance Show(RBT Char)
    instance(Show a)=>RBT a来解决这个问题

  • 您可能想要写的是“通过显示一组字符中的字符来显示一组字符”

    因此,要修复您的实例:

    instance Show (RBT Char) where
        show a = "something"
    
    但它没有显示任何有用的东西。您需要对RBT的构造函数进行模式匹配以完成工作:

    instance Show (RBT Char) where
        show E = "something"
        show (T a b c d) = "something else"
    

    但是对于您的任务来说,只需为
    RBT a
    Color
    使用派生的
    Show
    实例将值转换为字符串就更简单了,Haskell使用了所谓的类型类。简化的类型类只提供根据参数类型不同而表现不同的函数。这种方法与面向对象编程语言中已知的方法重载非常相似。type类
    Show
    提供了一个名为
    Show
    的函数,该函数将某种类型的值转换为字符串。例如,表达式
    show 1
    生成字符串
    “1”
    。如果有一个函数
    show
    将某个类型的值转换为字符串,我们就说这个类型有一个type类
    show
    的实例。换句话说,有一个整数类型类
    Show
    的实例

    在ghci中计算表达式时,也会使用此
    show
    函数。因此,它告诉您没有实例
    (Show(Set Char))
    ,换句话说,它不知道如何将
    Set Char
    类型的值转换为字符串。对于自定义类型,如您的类型
    Set
    RBT
    Color
    ,您必须提供类型类
    Show
    的实例,以便在控制台上显示这些类型的值。要为类型
    Color
    定义类型类
    Show
    的实例,可以使用以下定义

    instance Show Color where:
      show R = "Red"
      show B = "Black"
    
    也就是说,如果将
    R
    写入ghci,它将打印
    红色
    。对于简单的Haskell数据类型,有一个
    Show
    type类的规范定义。例如,
    Color
    Show
    的规范定义如下

    instance Show Color where:
      show R = "R"
      show B = "B"
    
    为了避免用户定义这样的实例,Haskell提供了一种所谓的“派生机制”。也就是说,如果你写

      deriving (Show)
    
    定义数据类型后,编译器将为您的数据类型生成
    Show
    type类的规范实例

    data RBT e = E | T Color (RBT e) e (RBT e)
    
    如果一个数据类型使用另一个数据类型,则派生前者的
    Show
    实例将需要后者的
    Show
    实例。例如,考虑下面的数据类型。

    data RBT e = E | T Color (RBT e) e (RBT e)
    

    数据类型
    RBT
    在其定义中使用类型
    Color
    T
    构造函数的规范
    Show
    实例将以“T”开头,然后显示类型
    Color
    的值。因此,为
    RBT
    导出
    Show
    实例需要为
    Color
    导出
    Show
    实例,只需使用
    data Tree a=。。。派生(显示)
    派生(显示)
    附加到
    数据RBT的末尾…
    给出了以下错误消息:
    没有因数据类型声明的“派生”子句而产生的(显示颜色)实例
    只需将
    派生(显示)
    添加到
    数据颜色=R|B
      deriving (Show)
    
    data RBT e = E | T Color (RBT e) e (RBT e)