QuickCheck 具有智能构造函数的抽象数据类型的任意实例。

问题描述 投票:0回答:1

我是语言新手,想写第一个非平凡的程序。在写的过程中,我卡在了创建一个 Arbitrary 例子。然而,我想我接下来的问题指向我对几种应用型和单体型的理解普遍不足。因此,我希望能从下面的问题中获得基本的见解。谢谢你的帮助

我定义了一个 Address 类型和一个智能构造函数,其对各个字段的验证如下。

data Address = Address
    { street :: StreetName
    , streetExt :: Maybe StreetName
    , city :: CityName
    , zipCode :: ZipCode
    , country :: CC.CountryCode
    } deriving (Eq, Show)
mkAddress :: Text -> Maybe Text -> Text -> Text -> Text -> Maybe Address
mkAddress aStreet aStreetExt aCity aZipCode aCountry =
    Address <$> mkStreetName aStreet
            <*> Just (aStreetExt >>= mkStreetName)
            <*> mkCityName aCity
            <*> mkZipCode aZipCode
            <*> CC.fromMText aCountry

StreetName, CityNameZipCode 的新类型包装物。Text 用一个验证的智能构造函数,简单地限制这些字段的最大长度。该 streetExt 字段是可选的。国家代码使用 Data.ContryCodes.CountryCode.

整体类型是抽象的,定义模块只导出智能构造函数,但没有导出数据构造函数。

我现在试图为这个类型创建一个Arbitrary实例&gt。

instance Arbitrary D.Address where
    arbitrary = do
        maybeAddress <- D.mkAddress <$> arbitrary         -- streetName
                                    <*> return Nothing    -- streetExt
                                    <*> arbitrary         -- city
                                    <*> arbitrary         -- zipCode
                                    <*> elements ["DE", "FR", "AG", "RW"]   -- country
        return fromJust maybeAddress

然而,我被下面的类型检查器错误卡住了。

• Couldn't match type ‘Maybe a0 -> a0’ with ‘Gen D.Address’
      Expected type: Maybe D.Address -> Gen D.Address
      Actual type: Maybe D.Address -> Maybe a0 -> a0
• The function ‘return’ is applied to two arguments,
      but its type ‘(Maybe a0 -> a0)
                    -> Maybe D.Address -> Maybe a0 -> a0’
      has only three

从这个错误来看,我认为在Maybe里面封装Generator有问题,或者相反。但即使经过几次实验 liftjoin 我无法让它进行类型检查。因此,我怀疑我的心智模型对类型的封装方式和生成器单体的返回方式存在缺陷。

如果有人能指出我的错误,那将是非常好的.另外,我非常感谢对这种使用抽象类型和智能构造器的数据建模的评论--这是一般推荐的做法,还是会导致像我所面临的问题?

非常感谢!我是一个新的语言爱好者,正在尝试使用抽象类型和智能构造器来进行数据建模。

haskell abstract-data-type quickcheck
1个回答
1
投票

错误信息说的很清楚(虽然后续的解释是误导性的)。

The function ‘return’ is applied to two arguments

你有

return fromJust maybeAddress

你想

return (fromJust maybeAddress)
© www.soinside.com 2019 - 2024. All rights reserved.