‘继承’在 Haskell 中不同定义的数据类型之间显示

问题描述 投票:0回答:1
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 = " "

在上面的代码中,我创建了两种数据类型:“Player”和“Spot”,即“Just Player”或“None”。 现在我能够

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

haskell functional-programming
1个回答
0
投票

问题不止一个。

非详尽模式

错误信息

Non-exhaustive patterns in function show
告诉您有一个案例尚未处理。

GHC 可以告诉您,在编译时(或在 GHCi 中加载时),如果您打开 incomplete-patterns 标志:

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

要解决该问题,请将缺失的案例添加到

Spot
show
实例中:

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"

这两种替代方案使用不同的语法,但它们是等效的。无论您使用其中一种还是另一种,都是一个偏好问题。

© www.soinside.com 2019 - 2024. All rights reserved.