Haskell中不同定义的数据类型之间的“继承"

insrf1ej  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(204)
data Player =         User | COM  deriving Eq
data Spot   = JustA Player | None deriving Eq

instance Show Player where
    show User = "X"
    show COM  = "O"

instance Show Spot where
    show None = " "

字符串
在上面的代码中,我创建了两种数据类型,PlayerSpot,这是Just PlayerNone。现在我可以show JustA User来给予结果“X”,但这不起作用。我尝试了各种方法来使用示例,但它们对我不起作用。
给出的错误是:

ghci> tictactoe
The computer will go first as O

   |   |
---+---+---
 *** Exception: tictactoe.hs:11:5-19: Non-exhaustive patterns in function show


(当尝试show JustA COM时出现错误)

idv4meu8

idv4meu81#

问题不止一个

非穷举模式

错误消息Non-exhaustive patterns in function show告诉您有一个尚未处理的案例。
GHC可以告诉你,在编译时(或在GHCi中加载时),如果你打开不完整模式标志:

ghci> :set -fwarn-incomplete-patterns

字符串
这样,你不仅会收到GHCi的警告,还会告诉你问题在哪里:

Q77520101.hs:11:5: warning: [-Wincomplete-patterns]
    Pattern match(es) are non-exhaustive
    In an equation for `show':
        Patterns of type `Spot' not matched: JustA _
   |
11 |     show None = " "
   |     ^^^^^^^^^^^^^^^


不过,通常情况下,只打开包括incomplete-patterns:Wall在内的更广泛的标志集会更容易。
要解决这个问题,请将缺少的case添加到Spotshow示例中:

instance Show Spot where
    show None = " "
    show (JustA p) = "JustA " ++ show p


尽管如此,让编译器派生show示例更容易:

data Player =         User | COM  deriving (Eq, Show)
data Spot   = JustA Player | None deriving (Eq, Show)


当然,这不会给你给予完全相同的输出。使用这种替代方法,show User将返回User而不是X。然而,这被认为是惯用的。

安装

另一个问题可能与表达式show JustA User有关。如果你在GHCi中尝试它,它会给予你一个详细的错误消息:

ghci> show JustA User

<interactive>:2:1: error:
    * Couldn't match expected type: Player -> t
                  with actual type: [Char]
    * The function `show' is applied to two value arguments,
        but its type `(Player -> Spot) -> [Char]' has only one
      In the expression: show JustA User
      In an equation for `it': it = show JustA User
    * Relevant bindings include it :: t (bound at <interactive>:2:1)


函数show需要一个 * 单一 * 输入值,但由于Haskell的语法,像show JustA User这样的表达式在Haskell编译器看来就像是一个有两个参数的函数调用。
你至少可以通过两种方式来解决这个问题:

ghci> show (JustA User)
"JustA X"
ghci> show $ JustA User
"JustA X"


这两种方法使用不同的语法,但它们是等价的。使用哪一种是你的偏好问题。

相关问题