Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"derive makeArbitrary" error w/ strict types (8.0.1) #17

Closed
jonschoning opened this issue Jun 20, 2016 · 7 comments
Closed

"derive makeArbitrary" error w/ strict types (8.0.1) #17

jonschoning opened this issue Jun 20, 2016 · 7 comments

Comments

@jonschoning
Copy link

data NoteListItem = NoteListItem {
      noteListItemId     :: !Text
    , noteListItemHash   :: !Text
    , noteListItemTitle  :: !Text
    , noteListItemLength :: !Int
    , noteListItemCreatedAt :: !UTCTime
    , noteListItemUpdatedAt :: !UTCTime
    } deriving (Show, Eq, Data, Typeable, Generic, Ord)


$(derive makeArbitrary ''NoteListItem)


Exception when trying to run compile-time code:
      Could not convert (Bang,Type) to Type
(Bang NoSourceUnpackedness SourceLazy,ConT Data.Text.Internal.Text)
src/Language/Haskell/Convert.hs:(76,5)-(79,64): Non-exhaustive patterns in function conv

CallStack (from HasCallStack):
  error, called at src/Language/Haskell/Convert.hs:20:87 in derive-2.5.25-6jyS0d772bZHapQdVyiucF:Language.Haskell.Convert
    Code: derive makeArbitrary ''NoteListItem
@jonschoning jonschoning changed the title "derive makeArbitrary" error w/ strict types "derive makeArbitrary" error w/ strict types (8.0.1) Jun 20, 2016
@ndmitchell
Copy link
Owner

Works for me using Derive 2.5.25 and the test case below. Can you check with that test case and Derive version, and we can see where things differ.

{-# LANGUAGE TemplateHaskell, DeriveDataTypeable, DeriveGeneric, StandaloneDeriving #-}

module Example where

import Data.Text
import Data.Data
import GHC.Generics
import Data.Time.Clock
import Data.Derive.Arbitrary
import Test.QuickCheck
import Data.DeriveTH
import System.IO.Unsafe

data NoteListItem = NoteListItem {
      noteListItemId     :: !Text
    , noteListItemHash   :: !Text
    , noteListItemTitle  :: !Text
    , noteListItemLength :: !Int
    , noteListItemCreatedAt :: !UTCTime
    , noteListItemUpdatedAt :: !UTCTime
    } deriving (Show, Eq, Data, Typeable, Generic, Ord)

instance Arbitrary Text where
    arbitrary = return mempty

instance Arbitrary UTCTime where
    arbitrary = return $ unsafePerformIO getCurrentTime

$(derive makeArbitrary ''NoteListItem)


main = print =<< generate (arbitrary :: Gen NoteListItem)

@jonschoning
Copy link
Author

jonschoning commented Jun 20, 2016

The test case you posted above works fine - no issues.

I've created a minimal repo that reproduces the failing behavior for me here: https://github.com/jonschoning/derive-issue-17

*note - not a serious issue for me, but just curious if I'm using the library correctly or am misunderstanding something more basic about how ghc works.

@jonschoning
Copy link
Author

jonschoning commented Jun 20, 2016

another side note - what I don't quite understand is where it is getting SourceLazy from in
(Bang NoSourceUnpackedness SourceLazy,ConT Data.Text.Internal.Text)

I would think it should interpret all the fields as SourceStrict due to the bangs.

>>> import Derive17 
>>> :kind! Rep NoteListItem 
Rep NoteListItem :: * -> *
= D1
    ('MetaData
       "NoteListItem"
       "Derive17"
       "derive17-0.0.1-G2Y3UnpjaWJD80ZsMDbSig"
       'False)
    (C1
       ('MetaCons "NoteListItem" 'PrefixI 'True)
       ((S1
           ('MetaSel
              ('Just "noteListItemId")
              'NoSourceUnpackedness
              'SourceStrict
              'DecidedStrict)
           (Rec0 TE.Text)
         :*: (S1
                ('MetaSel
                   ('Just "noteListItemHash")
                   'NoSourceUnpackedness
                   'SourceStrict
                   'DecidedStrict)
                (Rec0 TE.Text)
              :*: S1
                    ('MetaSel
                       ('Just "noteListItemTitle")
                       'NoSourceUnpackedness
                       'SourceStrict
                       'DecidedStrict)
                    (Rec0 TE.Text)))
        :*: (S1
               ('MetaSel
                  ('Just "noteListItemLength")
                  'NoSourceUnpackedness
                  'SourceStrict
                  'DecidedUnpack)
               (Rec0 Int)
             :*: (S1
                    ('MetaSel
                       ('Just "noteListItemCreatedAt")
                       'NoSourceUnpackedness
                       'SourceStrict
                       'DecidedStrict)
                    (Rec0 UTCTime)
                  :*: S1
                        ('MetaSel
                           ('Just "noteListItemUpdatedAt")
                           'NoSourceUnpackedness
                           'SourceStrict
                           'DecidedStrict)
                        (Rec0 UTCTime)))))

@ndmitchell
Copy link
Owner

Thanks for the awesome test case - I've got a fix, just doing a buildbot test and then I'll release it.

I suspect the constructors are either strict, lazy or default. Within a module they are default, but once they leave a module they get given explicit values.

@jonschoning
Copy link
Author

oh ok.. thank you! I will read up on this behavior

@ndmitchell
Copy link
Owner

That behaviour is a complete guess - but it seems to fit with what we're seeing. I expect the two different modules is important.

ndmitchell added a commit that referenced this issue Jun 20, 2016
@ndmitchell
Copy link
Owner

Fixed in 2.5.26. Thanks for the awesome test case!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants