在 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
,它们是两个具有不兼容类型签名的不同函数。这与您的代码中的情况相同,只是 readsDefined
和 readsContent
都是 readsPrec
方法的(不同)实例化,即它们共享相同的 name 但仍然有不同的实现方式。
我创建了一个类似于 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
,它们是两个具有不兼容类型签名的不同函数。这与您的代码中的情况相同,只是 readsDefined
和 readsContent
都是 readsPrec
方法的(不同)实例化,即它们共享相同的 name 但仍然有不同的实现方式。