4

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

newtype SpecialId Int
    deriving (Eq, Ord, Show)

read "5" :: SpecialId如果我在 newtype 中派生 Read 它不起作用,我希望能够做到,它只适用于read "SpecialId 5" :: SpecialId. 我试过了

instance Read SpecialId where
    readsPrec _ s = read s

但这给了我

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

2 回答 2

9

这是可能的,因为 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
于 2017-11-02T13:28:18.693 回答
6

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

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

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

于 2017-11-02T13:38:59.097 回答