Haskell 为 newtype 读取的实例,它只是一个 int

Haskell instance read for newtype that is just an int

我是 Haskell 的新手,我希望能够使用新类型,这样我就可以分辨出什么是什么,但我还必须从字符串中读取它。我有

newtype SpecialId Int
    deriving (Eq, Ord, Show)

我希望能够 read "5" :: SpecialId 如果我在新类型中派生 Read 它不起作用,它只适用于 read "SpecialId 5" :: SpecialId。我试过了

instance Read SpecialId where
    readsPrec _ s = read s

但这给了我

SpecialId *** Exception: Prelude.read: no parse

这是可能的,因为 GHC 8.2 使用 -XDerivingStrategies:

{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE DerivingStrategies         #-}

newtype SpecialId = SpecialId Int
    deriving stock   (Eq, Ord, Show)
    deriving newtype Read

在 ghci 中:

ghci> read "5" :: SpecialId 
SpecialId 5

如果您愿意手动转发到 Int 实例,则不需要语言扩展:

instance Read SpecialId where
    readsPrec n s = [ (SpecialId x, y) | (x, y) <- readsPrec n s ]

尽管看起来这不是 readsPrec 的递归使用:我们调用 readsPrecInt 版本来获取 (Int, String) 对的列表,然后我们使用将每个 Int 包装在 SpecialId.

中的列表理解