无法在Haskell中打印自己的数据类型

时间:2018-04-07 22:24:33

标签: haskell

在花时间仔细检查此代码之前,请在粗体文字后面阅读下面的问题。如果你不能回答,我不想浪费你的时间。

好。我在Haskell中创建了自己的数据类型。它是

data Dialogue= Choice String [(String, Dialogue)] 
            | Action String Event
  -- deriving (Show)

请注意注释掉'衍生(显示)',这对我下面的问题非常重要。

我有一个名为对话的函数定义为

dialogue:: Game -> Dialogue -> IO Game
dialogue (Game n p ps) (Action s e) = do 
   putStrLn s
   return (e (Game n p ps))
dialogue (Game n p ps) (Choice s xs) = do
  putStrLn s
  let ys = [ fst a | a <- xs ]
  let i = [1..length ys]
  putStrLn (enumerate 1 ys)
  str <- getLine
  if str `elem` exitWords
  then do
     return (Game n p ps)
  else do
     let c = read str::Int
     if c `elem` i 
     then do 
        let ds = [ snd b | b <- xs ]
        let d = ds !! c
        putStrLn $ show d
        return (Game n p ps)
     else do
        error "error"

我的数据类型游戏定义为

data Game = Game Node Party [Party] | Won 
  deriving (Eq,Show)

事件是一种类型,由我自己定义为

type Event = Game -> Game

现在,这就是我的问题发生的地方。当我在cmd中加载此文件时,我包含派生(显示)在我的数据类型对话中,我收到以下错误:

* No instance for (Show Dialogue) arising from a use of `show'
* In the second argument of `($)', namely `(show d)'
  In a stmt of a 'do' block: putStrLn $ (show d)
  In the expression:
    do let ds = ...
       let d = ds !! c
       putStrLn $ (show d)
       return (Game n p ps)
    |
120 |          putStrLn $ (show d)

在我看来,我需要包含 deriving(Show),以便能够将此数据类型打印到控制台。但是,当我包含派生(显示)时,我收到此错误:

* No instance for (Show Event)
    arising from the second field of `Action' (type `Event')
    (maybe you haven't applied a function to enough arguments?)
  Possible fix:
    use a standalone 'deriving instance' declaration,
      so you can specify the instance context yourself
* When deriving the instance for (Show Dialogue)
   |
85 |   deriving Show

我花了很长时间试图找出这可能发生的原因。但我无法在网上发现似乎记录这一特定问题的任何地方。

任何帮助都是完美的,甚至只是指向适当解释的链接。

**编辑:**我的活动是类型同义词,因此我无法将派生展示添加到此

非常感谢

2 个答案:

答案 0 :(得分:4)

Event正如您所定义的那样,它是一个没有明智方法可展示的功能。您希望如何显示此信息?一个解决方案是import Text.Show.Functions,它有一个实例。

例如:

Prelude Text.Show.Functions> show (+ 1)
"<function>"

另一个解决方案是定义自己的show实例:

instance Show (a -> b) where
    show _ = "_"

答案 1 :(得分:3)

type Event = Game -> Game
data Dialogue= Choice String [(String, Dialogue)] 
            | Action String Event
  -- deriving (Show)

当编译器尝试为Show派生Dialogue时,Show变体中必须Event Action,但它不能 - Event是一项功能,功能无法获得自动派生的Show个实例。

您必须手动实施Show EventShow Dialogue。实现Show Dialogue的一种方法是:

instance Show Dialogue where
    show (Choice s ds) = " "  `intercalate`  ["Choice", show s, show ds]
    show (Action s e) = " "  `intercalate`  ["Action", show s]