在 Haskell 中读取实例

Read instance in Haskell

我创建了一个类似于 Maybe

的类型

data Defined a = Is a | Undefined

我制作了 Show 实例

instance Show a => Show (Defined a) where
    show (Is a) = show a
    show Undefined = "?"

所以,我尝试实现实例 Read

instance Read a => Read (Defined a) where
    readsPrec _ s = case (take 1 s) of
                    "?" -> [(Undefined,tail s)]
                    otherwise -> map (\(a,b) -> (Is a,b)) $ readsPrec 0 s

行得通,但我不明白为什么。为什么这里没有死循环:

otherwise -> map (\(a,b) -> (Is a,b)) $ readsPrec 0 s

readsPrec 0 s 尝试读取与输入中相同的字符串,不是吗?所以它必须去 otherwise 块并形成一个无限循环。但是代码确实有效。

readsPrec 0 s try to read the same string such as in input, isn't it?

是的,但不一样readsPrec!让我添加一些类型注释:

{-# LANGUAGE ScopedTypeVariables #-}

instance Read a => Read (Defined a) where
  readsPrec _ = readsDefined

readsDefined :: forall a . Read a => String -> ReadS (Defined a)
readsDefined s = case (take 1 s) of
                    "?" -> [(Undefined,tail s)]
                    otherwise -> map (\(a,b) -> (Is a,b)) $ readsContent s
 where readsContent :: String -> ReadS a
       readsContent = readsPrec 0

请注意,我无法在此处将 readsContent 替换为 readsDefined,它们是两个具有不兼容类型签名的不同函数。这与您的代码中的情况相同,只是 readsDefinedreadsContent 都是 readsPrec 方法的(不同)实例化,即它们共享相同的 name 但仍然有不同的实现方式。