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

Ros*_*hur 4 haskell deriving newtype

我是Haskell的新手,我希望能够使用newtype,因此我可以告诉它是什么,但我也必须从字符串中读取它.我有

newtype SpecialId Int
    deriving (Eq, Ord, Show)
Run Code Online (Sandbox Code Playgroud)

我想能够read "5" :: SpecialId如果我在新类型中导出读取它不起作用它只能工作read "SpecialId 5" :: SpecialId.我试过了

instance Read SpecialId where
    readsPrec _ s = read s
Run Code Online (Sandbox Code Playgroud)

但这给了我

SpecialId *** Exception: Prelude.read: no parse
Run Code Online (Sandbox Code Playgroud)

She*_*rsh 9

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

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

newtype SpecialId = SpecialId Int
    deriving stock   (Eq, Ord, Show)
    deriving newtype Read
Run Code Online (Sandbox Code Playgroud)

在ghci:

ghci> read "5" :: SpecialId 
SpecialId 5
Run Code Online (Sandbox Code Playgroud)


mel*_*ene 6

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

instance Read SpecialId where
    readsPrec n s = [ (SpecialId x, y) | (x, y) <- readsPrec n s ]
Run Code Online (Sandbox Code Playgroud)

尽管出场,这不是一个递归使用readsPrec:我们所说的Int版本readsPrec得到的名单(Int, String)对,然后我们用一个列表理解来包装每Int一个SpecialId.